wa test3,20求助
查看原帖
wa test3,20求助
1122530
elpsconr楼主2024/9/12 15:49

思路仿照题解光速幂 却值得了90分,求助不知道哪里写挂了

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'//?
#define PII pair<int,int>
#define tul tuple<int,int,int>
#define all(x) x.begin(),x.end()
#define cy cout<<"Yes"<<endl
#define cn cout<<"No"<<endl 
#define lc (rt<<1)
#define rc (rt<<1|1)
const int N=3e5+6,yyx=1e4;
int n,m,p,c,phi[N],cnt,ok,a[N];
int po[yyx+5][64][2],ov[yyx+5][64][2];
int erlu(int x){
    int ans=x;
    for(int i=2;i*i<=x;++i){
        if(x%i==0){
            ans=ans/i*(i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x>=2) ans=ans/x*(x-1);
    return ans;
}
void init(){
    int x=p;
    phi[0]=p;
    while(x>1){
       x=erlu(x);
       phi[++cnt]=x;
    }
    phi[++cnt]=1;
    for(int i=0;i<=cnt;++i){
        po[0][i][0]=1; 
        for(int j=1;j<=yyx;++j){
            po[j][i][0]=po[j-1][i][0]*c;
            if(po[j][i][0]>=phi[i]) po[j][i][0]%=phi[i],ov[j][i][0]=1;
            ov[j][i][0]|=ov[j-1][i][0];
        }
    }
    for(int i=0;i<=cnt;++i){
        po[0][i][1]=1;
        for(int j=1;j<=yyx;++j){
            po[j][i][1]=po[j-1][i][1]*po[yyx][i][0];
            if(po[j][i][1]>=phi[i]) po[j][i][1]%=phi[i],ov[j][i][1]=1;
            ov[j][i][1]|=ov[j-1][i][1];
        }
    }
}
int qmi(int a,int b){
    ok|=ov[a%yyx][b][0]|ov[a/yyx][b][1];
    int res=po[a%yyx][b][0]*po[a/yyx][b][1];
    if(res>=phi[b]) ok=0,res%=phi[b];
    return res;
}
int cal(int x,int d,int b){
    ok=0;
    if(b==d){
      if(a[x]>=phi[b]){
        ok=1;
        return a[x]%phi[b];
      }
      return a[x];
    }
    int xx=cal(x,d,b+1);
    if(ok) xx+=phi[b+1],ok=0;
    return qmi(xx,b);
}
struct node{
    int l,r,sum,tag;
};
struct LSGT{
   vector<node> tree;
   //vector<int> a;
   LSGT(int n){
    tree.resize(4*n,{0,0,0,0});
    //a.resize(n+1,0);
   }
   void pushup(int rt){
    tree[rt].sum=(tree[lc].sum+tree[rc].sum)%p;
    tree[rt].tag=min(tree[lc].tag,tree[rc].tag);
   }
   void lazy(node &rt,int k){
    rt.tag+=k;
    rt.sum+=(rt.r-rt.l+1)*k;
   }
   void pushdown(int rt){
    if(tree[rt].tag){
       lazy(tree[lc],tree[rt].tag);
       lazy(tree[rc],tree[rt].tag);
       tree[rt].tag=0;
    }
   }
   void build(int rt,int l,int r){
    tree[rt]={l,r,a[l],0};
    if(l==r) return;
    int m=tree[rt].l+tree[rt].r>>1;
    build(lc,l,m);build(rc,m+1,r);
    pushup(rt);
   }
   void update(int rt,int x,int y){
    if(tree[rt].tag>=cnt) return;
    if(tree[rt].l==tree[rt].r){
        //lazy(tree[rt],k);
        tree[rt].tag++;
        tree[rt].sum=cal(tree[rt].l,tree[rt].tag,0);
    }
    else{
        int m=tree[rt].l+tree[rt].r>>1;
        //pushdown(rt);
        if(x<=m) update(lc,x,y);
        if(y>m) update(rc,x,y);
        pushup(rt);
    }
   }
   int query(int rt,int x,int y){
    if(tree[rt].l>=x&&tree[rt].r<=y) return tree[rt].sum;
    int m=tree[rt].l+tree[rt].r>>1;
    //pushdown(rt);
    int ans=0;
    if(x<=m) ans+=query(lc,x,y);
    if(y>m) ans+=query(rc,x,y);
    ans%=p;
    return ans;
   }
};
inline void solve(){
  cin>>n>>m>>p>>c;
  init();
  LSGT seg(n+1);
  for(int i=1;i<=n;++i) cin>>a[i];
  seg.build(1,1,n);
  while(m--){
    int ch,l,r;cin>>ch>>l>>r;
    if(!ch) seg.update(1,l,r);
    else cout<<seg.query(1,l,r)<<endl;
  }
}
signed main(){
  cin.tie(0)->sync_with_stdio(0);
  //freopen("D://321//in.txt","r",stdin);
  //freopen("D://321//out.txt","w",stdout);
  int _=1;
  //cin>>_;
  while(_--)
  solve();
  return 0;
}
2024/9/12 15:49
加载中...