洛谷3373 线段树2(线段树)

xiaoxiao2025-05-24  34

传送门

【题目分析】

RT,就是线段树的模板,支持区间乘、区间加、区间求和。

很有意思的一点是两个标记的下传,解决了就行了。

然后这道题,作为AHOI,竟然是个裸的模板!(可能年份久远的原因吧。。。)两个一毛一样嘛!

【代码~】

#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL MAXN=5e5+10; struct Tree{ LL l,r; LL sum,add,mul; }tr[MAXN<<2]; LL n,q,mod; LL a[MAXN]; LL Read() { LL i=0,f=1; char c; for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0'; return i*f; } void sc(LL x) { if(x>=10) sc(x/10); putchar(x%10+48); } void push_up(LL root) { tr[root].sum=(tr[root<<1].sum+tr[root<<1|1].sum)%mod; } void push_down(LL root) { if(tr[root].mul!=1||tr[root].add) { LL mid=tr[root].l+tr[root].r>>1; tr[root<<1].sum=(tr[root<<1].sum*tr[root].mul+tr[root].add*(mid-tr[root].l+1))%mod; tr[root<<1|1].sum=(tr[root<<1|1].sum*tr[root].mul+tr[root].add*(tr[root].r-mid))%mod; tr[root<<1].add=(tr[root<<1].add*tr[root].mul+tr[root].add)%mod; tr[root<<1|1].add=(tr[root<<1|1].add*tr[root].mul+tr[root].add)%mod; tr[root<<1].mul=(tr[root<<1].mul*tr[root].mul)%mod; tr[root<<1|1].mul=(tr[root<<1|1].mul*tr[root].mul)%mod; tr[root].add=0; tr[root].mul=1; } } void build(LL root,LL l,LL r) { tr[root].mul=1; tr[root].l=l; tr[root].r=r; if(l==r) { tr[root].sum=a[l]; return ; } LL mid=l+r>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); push_up(root); } void update1(LL root,LL l,LL r,LL L,LL R,LL key) { push_down(root); if(r<L||l>R) return ; if(L<=l&&r<=R) { tr[root].add=(tr[root].add+key)%mod; tr[root].sum=(tr[root].sum+key*(r-l+1))%mod; return ; } LL mid=l+r>>1; if(R<=mid) update1(root<<1,l,mid,L,R,key); else { if(L>mid) update1(root<<1|1,mid+1,r,L,R,key); else update1(root<<1,l,mid,L,mid,key),update1(root<<1|1,mid+1,r,mid+1,R,key); } push_up(root); } void update2(LL root,LL l,LL r,LL L,LL R,LL key) { push_down(root); if(r<L||l>R) return ; if(L<=l&&r<=R) { tr[root].mul=(tr[root].mul*key)%mod; tr[root].sum=(tr[root].sum*key)%mod; return ; } LL mid=l+r>>1; if(R<=mid) update2(root<<1,l,mid,L,R,key); else { if(L>mid) update2(root<<1|1,mid+1,r,L,R,key); else update2(root<<1,l,mid,L,mid,key),update2(root<<1|1,mid+1,r,mid+1,R,key); } push_up(root); } LL query(LL root,LL l,LL r,LL L,LL R) { push_down(root); if(l>R||r<L) return 0; if(L<=l&&r<=R) return tr[root].sum; LL mid=l+r>>1; if(R<=mid) return query(root<<1,l,mid,L,R); else { if(L>mid) return query(root<<1|1,mid+1,r,L,R); else return query(root<<1,l,mid,L,mid)+query(root<<1|1,mid+1,r,mid+1,R); } } int main() { n=Read(),mod=Read(); for(LL i=1;i<=n;++i) a[i]=Read(); build(1,1,n); q=Read(); while(q--) { LL cz=Read(),l=Read(),r=Read(); if(cz==1) { LL val=Read(); update2(1,1,n,l,r,val); } else { if(cz==2) { LL val=Read(); update1(1,1,n,l,r,val); } else sc(query(1,1,n,l,r)%mod),puts(""); } } return 0; }

 

转载请注明原文地址: https://www.6miu.com/read-5030605.html

最新回复(0)