1. 程式人生 > >P3373 線段樹模板

P3373 線段樹模板

gif gpo pri ret ace d+ urn col play

好,這是一個線段樹模板。

技術分享圖片
  1 #include <cstdio>
  2 using namespace std;
  3 const long long int N=1000010;
  4 long long int sum[N],tag1[N],tag2[N],mo;
  5 
  6 void build(int l,int r,int o)
  7 {
  8     tag1[o]=1;
  9     if(l==r)
 10     {
 11         scanf ("%d",&sum[o]);
 12         return;
 13     }
14 int mid=(l+r)>>1; 15 build(l,mid,o<<1); 16 build(mid+1,r,o<<1|1); 17 sum[o]=(sum[o<<1]+sum[o<<1|1])%mo; 18 return; 19 } 20 void down(int l,int r,int o) 21 { 22 tag1[o<<1]=tag1[o<<1]*tag1[o]%mo; 23 tag1[o<<1|1]=tag1[o<<1
|1]*tag1[o]%mo; 24 tag2[o<<1]=(tag2[o<<1]*tag1[o]+tag2[o])%mo; 25 tag2[o<<1|1]=(tag2[o<<1|1]*tag1[o]+tag2[o])%mo; 26 int mid=(l+r)>>1; 27 sum[o<<1]=(sum[o<<1]*tag1[o]+tag2[o]*(mid-l+1))%mo; 28 sum[o<<1|1]=(sum[o<<1|1]*tag1[o]+tag2[o]*(r-mid))%mo;
29 tag1[o]=1; 30 tag2[o]=0; 31 return; 32 } 33 34 void add(int L,int R,int v,int l,int r,int o) 35 { 36 if(L<=l && r<=R) 37 { 38 tag2[o]=(tag2[o]+v)%mo; 39 sum[o]=(sum[o]+v*(r-l+1))%mo; 40 return; 41 } 42 if(r<L || R<l) return; 43 down(l,r,o); 44 int mid=(l+r)>>1; 45 if(L<=mid) add(L,R,v,l,mid,o<<1); 46 if(mid<R) add(L,R,v,mid+1,r,o<<1|1); 47 sum[o]=(sum[o<<1]+sum[o<<1|1])%mo; 48 return; 49 } 50 void mul(int L,int R,int v,int l,int r,int o) 51 { 52 if(L<=l && r<=R) 53 { 54 tag1[o]=tag1[o]*v%mo; 55 tag2[o]=tag2[o]*v%mo; 56 sum[o]=sum[o]*v%mo; 57 return; 58 } 59 if(r<L || R<l) return; 60 down(l,r,o); 61 int mid=(l+r)>>1; 62 if(L<=mid) mul(L,R,v,l,mid,o<<1); 63 if(mid<R) mul(L,R,v,mid+1,r,o<<1|1); 64 sum[o]=(sum[o<<1]+sum[o<<1|1])%mo; 65 return; 66 } 67 long long int ask_sum(int L,int R,int l,int r,int o) 68 { 69 if(L<=l && r<=R) return sum[o]; 70 if(r<L || R<l) return 0; 71 int mid=(l+r)>>1; 72 down(l,r,o); 73 long long int ans=ask_sum(L,R,l,mid,o<<1); 74 ans=ans+ask_sum(L,R,mid+1,r,o<<1|1)%mo; 75 sum[o]=(sum[o<<1]+sum[o<<1|1])%mo; 76 return ans%mo; 77 } 78 int main() 79 { 80 int n,m; 81 scanf ("%d%d%d",&n,&m,&mo); 82 build(1,n,1); 83 while(m--) 84 { 85 int flag,x,y,c; 86 scanf ("%d",&flag); 87 if(flag==1) 88 { 89 scanf ("%d%d%d",&x,&y,&c); 90 mul(x,y,c,1,n,1); 91 } 92 else if(flag==2) 93 { 94 scanf ("%d%d%d",&x,&y,&c); 95 add(x,y,c,1,n,1); 96 } 97 else 98 { 99 scanf ("%d%d",&x,&y); 100 printf("%lld\n",ask_sum(x,y,1,n,1)); 101 } 102 } 103 return 0; 104 }
模板在此

就這樣。

P3373 線段樹模板