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 模板的主要内容,如果未能解决你的问题,请参考以下文章

luogu P3373 模板线段树 2

原创洛谷 LUOGU P3373 模板线段树2

luogu P3373 模板线段树 2

Luogu P3373 模板线段树 2

P3373 模板线段树 2区间乘/加 区间查询

P3373 模板线段树 2 (未完待续)