线段树板子求调
查看原帖
线段树板子求调
177000
vicky2048_2楼主2023/10/10 20:53

rt,把找到的能模的地方都模了,开了unsigned ll(开LL也不能过),因为是动态开点所以空间只开了两倍(试过开四倍了,过不了……)

感觉自己写得很对但实际上只有30pts……

#include<bits/stdc++.h>
#define N 100005
#define int unsigned long long
using namespace std;
int n,mod,t,a[N],st,bh;
struct tree{
    int l,r,sum,add,mul;
}tr[N<<2];
void build(int&,int,int),add(int,int,int,int,int,int),mul(int,int,int,int,int,int),push(int,int,int);
int sum(int,int,int,int,int);
signed main(){
    scanf("%llu%llu%llu",&n,&t,&mod);
    for(int i=1;i<=n;++i)
        scanf("%llu",&a[i]);
    build(st,1,n);
    while(t--){
        int op,x,y,k;
        scanf("%llu%llu%llu",&op,&x,&y);
        if(op<3){
            scanf("%llu",&k);
            if(op&1)
                mul(1,1,n,x,y,k);
            else
                add(1,1,n,x,y,k);
        }
        else
            printf("%llu\n",sum(1,1,n,x,y));
    }
    return 0;
}
void build(int &no,int l,int r){
    if(!no) no=++bh;
    if(l==r){
        tr[no].sum=a[l],tr[no].mul=1;
        return ;
    }
    int mi=l+r>>1;
    build(tr[no].l,l,mi),build(tr[no].r,mi+1,r);
    tr[no].sum=(tr[tr[no].l].sum+tr[tr[no].r].sum)%mod;
    tr[no].mul=1;
}
void add(int no,int l,int r,int st,int en,int k){
    int lc=tr[no].l,rc=tr[no].r,mi=l+r>>1;
    if(l>=st&&r<=en){
        tr[no].add+=k,tr[no].add%=mod;
        tr[no].sum+=k*(r-l+1)%mod,tr[no].sum%=mod;
        return ;
    }
    push(no,l,r);
    if(st<=mi)
        add(lc,l,mi,st,en,k);
    if(en>mi)
        add(rc,mi+1,r,st,en,k);
    tr[no].sum=(tr[lc].sum+tr[rc].sum)%mod;
}
void mul(int no,int l,int r,int st,int en,int k){
    int mi=l+r>>1,lc=tr[no].l,rc=tr[no].r;
    if(l>=st&&r<=en){
        tr[no].sum*=k,tr[no].sum%=mod;
        tr[no].add*=k,tr[no].add%=mod;
        tr[no].mul*=k,tr[no].mul%=mod;
        return ;
    }
    push(no,l,r);
    if(en>mi)
        mul(rc,mi+1,r,st,en,k);
    if(st<=mi)
        mul(lc,l,mi,st,en,k);
    tr[no].sum=(tr[rc].sum+tr[lc].sum)%mod;
}
int sum(int no,int l,int r,int st,int en){
    int lc=tr[no].l,rc=tr[no].r,mi=l+r>>1;
    if(l>=st&&r<=en)
        return tr[no].sum;
    push(no,l,r);
    int ans=0;
    if(st<=mi)
        ans=sum(lc,l,mi,st,en);
    if(en>mi)
        ans+=sum(rc,mi+1,r,st,en),ans%=mod;
    return ans%mod;
}
void push(int no,int l,int r){
    int ad=tr[no].add,mu=tr[no].mul,lc=tr[no].l,rc=tr[no].r,mi=l+r>>1;
    tr[no].add=0,tr[no].mul=1;
    if(mu>1){
        tr[lc].mul*=mu,tr[lc].mul%=mod;
        tr[lc].add*=mu,tr[lc].add%=mod;
        tr[lc].sum*=mu,tr[lc].sum%=mod;
        tr[rc].mul*=mu,tr[rc].mul%=mod;
        tr[rc].add*=mu,tr[rc].add%=mod;
        tr[rc].sum*=mu,tr[rc].sum%=mod;
    }
    if(ad){
        tr[lc].sum+=ad*(mi-l+1)%mod,tr[lc].sum%=mod;
        tr[rc].sum+=ad*(r-mi)%mod,tr[rc].sum%=mod;
        tr[lc].add+=ad,tr[lc].add%=mod;
        tr[rc].add+=ad,tr[rc].add%=mod;
    }
}

2023/10/10 20:53
加载中...