线段树50pts 5TLE+4WA求调
查看原帖
线段树50pts 5TLE+4WA求调
537998
lpx2024楼主2024/6/10 15:04
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxN=200010;
int l[maxN],r[maxN],a[maxN],c[maxN],p[maxN],mod,q;
bool tag[maxN];
int len(int k){
    return r[k]-l[k]+1;
}
int pw(int x){
	int ans=1;
	if(x==0) return 1;
	for(int i=1;x;i++){
		if(x&1) ans=(ans*p[i])%mod;
		if(x==1) return ans;
		x/=2;
	}
}
void pushup(int k){
    c[k]=c[k*2]+c[k*2+1];
    tag[k] = tag[k*2]&tag[k*2+1];
}
void build(int x,int y,int k){
    l[k]=x,r[k]=y;
    if(x==y){
        c[k]=a[x];
        return;
    }
    int mid=(x+y)/2;
    build(x,mid,k*2);
    build(mid+1,y,k*2+1);
    pushup(k);
}
void update(int x,int y,int k){
    if(tag[k]) return;
    if(l[k] == r[k]){
		if(c[k] == pw(c[k])) tag[k]=1;
        else c[k]=pw(c[k]);
        return;
    }
    int mid=(l[k]+r[k])/2;
    if(x<=mid) update(x,y,k*2);
    if(y>mid) update(x,y,k*2+1);
    pushup(k);
}
int query(int x,int y,int k){
    if(x<=l[k] && r[k]<=y) return c[k];
    int mid=(l[k]+r[k])/2,ans=0;
    if(x<=mid) ans+=query(x,y,k*2);
    if(y>mid) ans+=query(x,y,k*2+1);
    return ans;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    long long n,m;
    cin>>n>>m>>mod>>q;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,n,1);
    p[1]=q;
    for(int i=2;i<=200;i++) p[i]=(p[i-1]*p[i-1])%mod;
    for(int i=1;i<=m;i++){
        int op,x,y;
        cin>>op>>x>>y;
        //if(x>y)swap(x,y);
        if(op==1) cout<<query(x,y,1)%mod<<endl;
        else update(x,y,1);
    }
    return 0;
}
2024/6/10 15:04
加载中...