[有关注为回报] 再 次 求 调 分 块
查看原帖
[有关注为回报] 再 次 求 调 分 块
253765
houpingze楼主2021/1/27 21:32

rt,目前只要求正确性,卡常到时候我换读优就行了,不需要卡常,求改/kk

#include<bits/stdc++.h>
#define reg register int
#define INF (1<<30)
#define int long long
using namespace std;
 int p;
int read(){
    int res=0,fs=1; char c=getchar();
    while(!(c>='0' && c<='9')){ if(c=='-')fs=-1; c=getchar(); }
    while(c>='0' && c<='9')res=res*10+(c^48),c=getchar();
    return res*fs;
}
void print(int x){
    if(x<0) { putchar('-'); x=-x;}
    if(x>9) print(x/10);
    putchar(x%10+'0');
}
int S;
int lazy[200005]; 
int n,cnt,m,a[200005],ans,tmp,l,r,k,z,x[200005],y[200005],id[200005],v[1010];
inline void sh1(int l,int r,int k){  
    int ll=id[l],rr=id[r]; 
    if(ll==rr){
        for(int i=l;i<=r;i++) a[i]+=k,v[ll]+=k;
        return ;
    } 
    for(int i=ll+1;i<=rr-1;++i) {
        v[i]+=k*(y[i]-x[i]+1);
        lazy[i]+=k;     
    } 
    for(int i=l;i<=y[ll];++i) a[i]+=k,v[ll]+=k;
    for(int i=x[rr];i<=r;++i) a[i]+=k,v[rr]+=k;
}
int lazy2[2020];
inline void sh2(int l,int r,int k){  
    int ll=id[l],rr=id[r]; 
    if(ll==rr){
        for(int i=l;i<=r;i++) v[ll]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[ll]%=p;
        return ;
    } 
    for(int i=ll+1;i<=rr-1;++i) {
        v[i]*=k;
        v[i]%=p;
        if(lazy[i]==0) lazy[i]=k;
        else lazy[i]*=k,lazy[i]%=p;
    } 
    for(int i=l;i<=y[ll];++i) v[ll]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[ll]%=p;
    for(int i=x[rr];i<=r;++i) v[rr]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[rr]%=p;
}
inline int cx(int l,int r){
    //l~~r
    int ll=id[l],rr=id[r];
    int ret=0;
    if(ll==rr){
        for(int i=l;i<=r;i++) ret+=a[i]+lazy[ll],ret%=p;
        return ret;
    } 
    for(int i=ll+1;i<=rr-1;++i) ret+=v[i],ret%=p;

    ret%=p;
    for(int i=l;i<=y[ll];++i) ret+=a[i]+lazy[id[i]],ret%=p;
    ret%=p;
    for(int i=x[rr];i<=r;++i) ret+=a[i]+lazy[id[i]],ret%=p;
    return ret; 
}

signed main() { 
//    ios::sync_with_stdio(false);
    cin>>n>>m>>p;  
    for(int i=1;i<=n;i++) a[i]=read();
    S=sqrt(n); 
    for(int i=1;i<=S;i++){
        x[i]=(i-1)*S+1,y[i]=min(i*S,n);
    } 
    if(x[S]<n) S++,x[S]=y[S-1]+1,y[S]=n; 
    for(int i=1;i<=S;i++){ 
        for(int j=x[i];j<=y[i];j++) id[j]=i,v[i]+=a[j];
    } 
    while(m--){
        int op;
        cin>>op;
        if(op==2){
            cin>>l>>r>>k; 
            sh1(l,r,k); 
        }else if(op==1){
            cin>>l>>r>>k; 
            
            sh2(l,r,k); 
        }else if(op==3){
            cin>>l>>r; 
            cout<<cx(l,r)%p<<'\n';
        }

    }
    return 0;
}
2021/1/27 21:32
加载中...