老坑了。
之前比较困然后没调出来,之前比较颓不想调毒瘤题。
做过类似的splay题,然后这题没啥好说的,开LL。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; LL mod; struct node { int l,r,lc,rc; LL sum; LL tipj,tipc; }tr[210000];int trlen; int a[110000]; void bt(int l,int r) { int now=++trlen; tr[now].l=l;tr[now].r=r; if(l==r) { tr[now].lc=tr[now].rc=0; tr[now].sum=a[l]; tr[now].tipj=0;tr[now].tipc=1; } else { int mid=(l+r)/2; tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); tr[now].sum=(tr[tr[now].lc].sum+tr[tr[now].rc].sum)%mod; tr[now].tipj=0;tr[now].tipc=1; } } void wh(int now) { int lc=tr[now].lc,rc=tr[now].rc; if(tr[now].tipc!=1) { tr[lc].sum=(tr[lc].sum*tr[now].tipc)%mod; tr[lc].tipj=(tr[lc].tipj*tr[now].tipc)%mod; tr[lc].tipc=(tr[lc].tipc*tr[now].tipc)%mod; tr[rc].sum=(tr[rc].sum*tr[now].tipc)%mod; tr[rc].tipj=(tr[rc].tipj*tr[now].tipc)%mod; tr[rc].tipc=(tr[rc].tipc*tr[now].tipc)%mod; tr[now].tipc=1; } if(tr[now].tipj!=0) { int L; L=tr[lc].r-tr[lc].l+1; tr[lc].sum=(tr[lc].sum+L*tr[now].tipj)%mod; tr[lc].tipj=(tr[lc].tipj+tr[now].tipj)%mod; L=tr[rc].r-tr[rc].l+1; tr[rc].sum=(tr[rc].sum+L*tr[now].tipj)%mod; tr[rc].tipj=(tr[rc].tipj+tr[now].tipj)%mod; tr[now].tipj=0; } } void mul(int now,int l,int r,LL k) { if(tr[now].l==l&&tr[now].r==r) { wh(now); tr[now].sum=(tr[now].sum*k)%mod; tr[now].tipj=(tr[now].tipj*k)%mod; tr[now].tipc=(tr[now].tipc*k)%mod; return ; } wh(now); int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) mul(lc,l,r,k); else if(mid+1<=l)mul(rc,l,r,k); else mul(lc,l,mid,k), mul(rc,mid+1,r,k); //jc tr[now].sum=(tr[lc].sum+tr[rc].sum)%mod; } void add(int now,int l,int r,LL k) { if(tr[now].l==l&&tr[now].r==r) { wh(now); int L=r-l+1; tr[now].sum=(tr[now].sum+L*k)%mod; tr[now].tipj=(tr[now].tipj+k)%mod; return ; } wh(now); int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) add(lc,l,r,k); else if(mid+1<=l)add(rc,l,r,k); else add(lc,l,mid,k), add(rc,mid+1,r,k); //jc tr[now].sum=(tr[lc].sum+tr[rc].sum)%mod; } LL getsum(int now,int l,int r) { if(tr[now].l==l&&tr[now].r==r)return tr[now].sum; wh(now); int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) return getsum(lc,l,r); else if(mid+1<=l)return getsum(rc,l,r); else return (getsum(lc,l,mid)+getsum(rc,mid+1,r))%mod; } int main() { int n; scanf("%d%lld",&n,&mod); for(int i=1;i<=n;i++)scanf("%d",&a[i]); trlen=0;bt(1,n); int m,op,l,r;LL k; scanf("%d",&m); while(m--) { scanf("%d",&op); if(op==1) { scanf("%d%d%lld",&l,&r,&k); mul(1,l,r,k%mod); } else if(op==2) { scanf("%d%d%lld",&l,&r,&k); add(1,l,r,k%mod); } else { scanf("%d%d",&l,&r); printf("%lld\n",getsum(1,l,r)); } } return 0; }