线段树30分求调
查看原帖
线段树30分求调
407223
TulipeNoire楼主2021/9/10 19:43

rt,蒟蒻检查很久都看不出来。错1,3,4。

#include <bits/stdc++.h>
#define N 100003
using namespace std;
int n,m;
long long a[N],d[4*N],b[4*N],c[4*N],mod;
void build(int l,int r,int p) {
    c[p]=1;
    if (l==r) {
        d[p]=a[l];
        return;
    }
    int mid=l+((r-l)>>1);
    build(l,mid,p*2);
    build(mid+1,r,p*2+1);
    d[p]=d[p*2]+d[p*2+1];
}
void upd1(int tl,int tr,int l,int r,long long dt,int p) {
    if (tl<=l&&r<=tr) {
        d[p]+=(r-l+1)*dt,d[p]%=mod,b[p]+=dt,b[p]%=mod;
        return;
    }
    int mid=l+((r-l)>>1);
    if ((b[p]||c[p]!=1)&&l!=r) {
        d[p*2]*=c[p];
        d[p*2]%=mod;
        d[p*2]+=(mid-l+1)*b[p];
        d[p*2]%=mod;
        d[p*2+1]*=c[p];
        d[p*2+1]%=mod;
        d[p*2+1]+=(r-mid)*b[p];
        d[p*2+1]%=mod;
        b[p*2]+=b[p];
        c[p*2]*=c[p]; 
        b[p*2+1]+=b[p];
        c[p*2+1]*=c[p];
        b[p*2]%=mod;
        c[p*2]%=mod;
        b[p*2+1]%=mod;
        c[p*2+1]%=mod;
        b[p]=0; 
        c[p]=1;
    }
    if (tl<=mid) upd1(tl,tr,l,mid,dt,p*2);
    if (tr>mid) upd1(tl,tr,mid+1,r,dt,p*2+1);
    d[p]=d[p*2]+d[p*2+1];
    return; 
}
void upd2(int tl,int tr,int l,int r,long long dt,int p) {
    if (tl<=l&&r<=tr) {
        d[p]*=dt,d[p]%=mod,c[p]*=dt,c[p]%=mod,b[p]*=dt,b[p]%=mod;
        return;
    }
    int mid=l+((r-l)>>1);
    if ((b[p]||c[p]!=1)&&l!=r) {
        d[p*2]*=c[p];
        d[p*2]%=mod;
        d[p*2]+=(mid-l+1)*b[p];
        d[p*2]%=mod;
        d[p*2+1]*=c[p];
        d[p*2+1]%=mod;
        d[p*2+1]+=(r-mid)*b[p];
        d[p*2+1]%=mod;
        b[p*2]+=b[p];
        c[p*2]*=c[p]; 
        b[p*2+1]+=b[p];
        c[p*2+1]*=c[p];
        b[p*2]%=mod;
        c[p*2]%=mod;
        b[p*2+1]%=mod;
        c[p*2+1]%=mod;
        b[p]=0; 
        c[p]=1;
    }
    if (tl<=mid) upd2(tl,tr,l,mid,dt,p*2);
    if (tr>mid) upd2(tl,tr,mid+1,r,dt,p*2+1);
    d[p]=d[p*2]+d[p*2+1];
    return; 
}
long long getsum(int tl,int tr,int l,int r,int p) {
    if (tl<=l&&r<=tr) {
        return d[p];
    }
    int mid=l+((r-l)>>1);
    if ((b[p]||c[p]!=1)&&l!=r) {
        d[p*2]*=c[p];
        d[p*2]%=mod;
        d[p*2]+=(mid-l+1)*b[p];
        d[p*2]%=mod;
        d[p*2+1]*=c[p];
        d[p*2+1]%=mod;
        d[p*2+1]+=(r-mid)*b[p];
        d[p*2+1]%=mod;
        b[p*2]+=b[p];
        c[p*2]*=c[p]; 
        b[p*2+1]+=b[p];
        c[p*2+1]*=c[p];
        b[p*2]%=mod;
        c[p*2]%=mod;
        b[p*2+1]%=mod;
        c[p*2+1]%=mod;
        b[p]=0; 
        c[p]=1;
    }
    long long sum=0;
    if (tl<=mid) sum+=getsum(tl,tr,l,mid,p*2);
    sum%=mod;
    if (tr>mid) sum+=getsum(tl,tr,mid+1,r,p*2+1);
    return sum%mod;
}
int main() {
    scanf("%d %d %lld",&n,&m,&mod);
    for (int i=1;i<=n;i++) {
        scanf("%lld",&a[i]);
    }
    build(1,n,1);
    for (int i=1;i<=m;i++) {
        int opt,x,y;
        long long k;
        scanf("%d",&opt);
        if (opt==1) {
            scanf("%d %d %lld",&x,&y,&k);
            upd2(x,y,1,n,k,1); 
        } else if (opt==2) {
            scanf("%d %d %lld",&x,&y,&k);
            upd1(x,y,1,n,k,1); 
        } else {
            scanf("%d %d",&x,&y);
            printf("%lld\n",getsum(x,y,1,n,1));
        }
    }
    return 0;
}
2021/9/10 19:43
加载中...