luogu P3373 线段树2 模板
Posted Misaka_Azusa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P3373 线段树2 模板相关的知识,希望对你有一定的参考价值。
题目链接:https://www.luogu.org/problemnew/show/P3373
lazy标记两个,先乘后加
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define lson left, mid, rt<<1 6 #define rson mid+1, right, rt<<1|1 7 #define ll long long 8 using namespace std; 9 const int maxn = 100010; 10 ll n, m, addlazy[maxn<<2], mullazy[maxn<<2], ans[maxn<<2], mod, x,y,k; 11 void PushUP(ll rt) 12 { 13 ans[rt] = (ans[rt<<1] + ans[rt<<1|1])%mod; 14 } 15 void build(ll left, ll right, ll rt) 16 { 17 addlazy[rt] = 0; 18 mullazy[rt] = 1; 19 if(right == left) 20 { 21 scanf("%d",&ans[rt]); 22 return ; 23 } 24 ll mid = (left+right) >> 1; 25 build(lson); 26 build(rson); 27 PushUP(rt); 28 } 29 void PushDOWN(ll rt, ll mid, ll left, ll right) 30 { 31 mullazy[rt<<1]=(mullazy[rt<<1]*mullazy[rt])%mod; 32 mullazy[rt<<1|1]=(mullazy[rt<<1|1]*mullazy[rt])%mod; 33 addlazy[rt<<1]=(addlazy[rt<<1]*mullazy[rt])%mod; 34 addlazy[rt<<1|1]=(addlazy[rt<<1|1]*mullazy[rt])%mod; 35 ans[rt<<1]=(ans[rt<<1]*mullazy[rt])%mod; 36 ans[rt<<1|1]=(ans[rt<<1|1]*mullazy[rt])%mod; 37 mullazy[rt]=1; 38 addlazy[rt<<1]=(addlazy[rt<<1]+addlazy[rt])%mod; 39 addlazy[rt<<1|1]=(addlazy[rt<<1|1]+addlazy[rt])%mod; 40 ans[rt<<1]=(ans[rt<<1]+(mid-left+1)*addlazy[rt])%mod; 41 ans[rt<<1|1]=(ans[rt<<1|1]+(right-mid)*addlazy[rt])%mod; 42 addlazy[rt]=0; 43 } 44 void mulupdate(ll l, ll r, ll add, ll left, ll right, ll rt) 45 { 46 if(l<=left&&r>=right) 47 { 48 addlazy[rt] = (addlazy[rt]*add)%mod; 49 mullazy[rt] = (mullazy[rt]*add)%mod; 50 ans[rt] = (add*ans[rt])%mod; 51 return; 52 } 53 ll mid = (left+right)>>1; 54 if(mullazy[rt]!=1||addlazy[rt]>=1) PushDOWN(rt,mid,left,right); 55 if(l<=mid) mulupdate(l,r,add,lson); 56 if(r>mid) mulupdate(l,r,add,rson); 57 PushUP(rt); 58 } 59 void addupdate(ll l, ll r, ll add, ll left, ll right, ll rt) 60 { 61 if(l<=left&&r>=right) 62 { 63 addlazy[rt]= (addlazy[rt]+add)%mod; 64 ans[rt] = (ans[rt] + add*(right-left+1))%mod; 65 return; 66 } 67 ll mid = (left+right)>>1; 68 if(mullazy[rt]!=1||addlazy[rt]>=1) PushDOWN(rt,mid,left,right); 69 if(l<=mid) addupdate(l,r,add,lson); 70 if(r>mid) addupdate(l,r,add,rson); 71 PushUP(rt); 72 } 73 ll query(ll l, ll r, ll left, ll right, ll rt) 74 { 75 ll res = 0; 76 if(l <= left&&r >= right) return ans[rt]%mod; 77 ll mid = (left+right) >> 1; 78 if(mullazy[rt]!=1||addlazy[rt]>=1) PushDOWN(rt, mid, left, right); 79 if(l <= mid) res = (res+query(l,r,lson))%mod; 80 if(r > mid) res = (res+query(l,r,rson))%mod; 81 return res%mod; 82 } 83 int main() 84 { 85 scanf("%d%d%d",&n,&m,&mod); 86 build(1,n,1); 87 while(m--) 88 { 89 int p; 90 scanf("%d",&p); 91 if(p == 1) 92 { 93 scanf("%d%d%d",&x,&y,&k); 94 mulupdate(x,y,k,1,n,1); 95 } 96 if(p == 2) 97 { 98 scanf("%d%d%d",&x,&y,&k); 99 addupdate(x,y,k,1,n,1); 100 } 101 if(p == 3) 102 { 103 scanf("%d%d",&x,&y); 104 printf("%d\n",query(x,y,1,n,1)); 105 } 106 } 107 return 0; 108 }
以上是关于luogu P3373 线段树2 模板的主要内容,如果未能解决你的问题,请参考以下文章