1. 程式人生 > >線段樹區間更新 lazy

線段樹區間更新 lazy

spa clas mat bitset 2.7 efi push ace bsp

1.

hdu1698

http://acm.hdu.edu.cn/showproblem.php?pid=1698

  1 /*
  2 x y k
  3 x~y的值變為k
  4 */
  5 #include <cstdio>
  6 #include <cstdlib>
  7 #include <cmath>
  8 #include <cstring>
  9 #include <time.h>
 10 #include <string>
 11 #include <set>
 12 #include <map>
 13
#include <list> 14 #include <stack> 15 #include <queue> 16 #include <vector> 17 #include <bitset> 18 #include <ext/rope> 19 #include <algorithm> 20 #include <iostream> 21 using namespace std; 22 #define ll long long 23 #define minv 1e-6 24 #define
inf 1e9 25 #define pi 3.1415926536 26 #define E 2.7182818284 27 const ll mod=1e9+7;//998244353 28 const int maxn=1e5+10; 29 30 int tag[maxn<<2],sum[maxn<<2]; 31 32 void push_down(int index,int len) 33 { 34 tag[index<<1]=tag[index<<1|1]=tag[index]; 35 sum[index<<1
]=((len+1)>>1)*tag[index]; 36 sum[index<<1|1]=(len>>1)*tag[index]; 37 tag[index]=0; 38 } 39 40 void build(int index,int l,int r) 41 { 42 tag[index]=0; 43 if (l==r) 44 sum[index]=1; 45 else 46 { 47 int m=(l+r)>>1; 48 build(index<<1,l,m); 49 build(index<<1|1,m+1,r); 50 sum[index]=sum[index<<1]+sum[index<<1|1]; 51 } 52 } 53 54 void update(int index,int l,int r,int x,int y,int k) 55 { 56 if (x<=l && r<=y) 57 { 58 tag[index]=k; 59 sum[index]=(r-l+1)*k; 60 return; 61 } 62 if (tag[index]!=0) 63 push_down(index,r-l+1); 64 int m=(l+r)>>1; 65 if (x<=m) 66 update(index<<1,l,m,x,y,k); 67 if (m<y) 68 update(index<<1|1,m+1,r,x,y,k); 69 sum[index]=sum[index<<1]+sum[index<<1|1]; 70 } 71 72 int query(int index,int l,int r,int s,int t) 73 { 74 if (s<=l && r<=t) 75 return sum[index]; 76 if (r<s || l>t) 77 return 0; 78 if (tag[index]!=0) 79 push_down(index,r-l+1); 80 int m=(l+r)>>1; 81 return query(index<<1,l,m,s,t)+query(index<<1|1,m+1,r,s,t); 82 } 83 84 int main() 85 { 86 int t,T,n,q,x,y,k; 87 scanf("%d",&t); 88 for (T=1;T<=t;T++) 89 { 90 scanf("%d",&n); 91 build(1,1,n); 92 scanf("%d",&q); 93 while (q--) 94 { 95 scanf("%d%d%d",&x,&y,&k); 96 update(1,1,n,x,y,k); 97 } 98 printf("Case %d: The total value of the hook is %d.\n",T,query(1,1,n,1,n)); 99 } 100 return 0; 101 }

2.

https://www.luogu.org/problemnew/show/P3372

  1 /*
  2 第八個測試數據有問題(已看)
  3 
  4 操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k
  5 
  6 操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和
  7 */
  8 #include <cstdio>
  9 #include <cstdlib>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <time.h>
 13 #include <string>
 14 #include <set>
 15 #include <map>
 16 #include <list>
 17 #include <stack>
 18 #include <queue>
 19 #include <vector>
 20 #include <bitset>
 21 #include <ext/rope>
 22 #include <algorithm>
 23 #include <iostream>
 24 using namespace std;
 25 #define ll long long
 26 #define minv 1e-6
 27 #define inf 1e9
 28 #define pi 3.1415926536
 29 #define E  2.7182818284
 30 const ll mod=1e9+7;//998244353
 31 const int maxn=1e5+10;
 32 
 33 ll sum[maxn<<2],tag[maxn<<2];
 34 
 35 void build(int index,int l,int r)
 36 {
 37     tag[index]=0;
 38     if (l==r)
 39     {
 40         scanf("%lld",&sum[index]);
 41         sum[index]=sum[index]%mod;
 42     }
 43     else
 44     {
 45         int m=(l+r)>>1;
 46         build(index<<1,l,m);
 47         build(index<<1|1,m+1,r);
 48         sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
 49     }
 50 }
 51 
 52 void pushdown(int index,ll len)
 53 {
 54     sum[index<<1]=(tag[index]*((len+1)>>1) +sum[index<<1])%mod;
 55     sum[index<<1|1]=(tag[index]*(len>>1) +sum[index<<1|1])%mod;
 56     tag[index<<1]=(tag[index]+ tag[index<<1])%mod;
 57     tag[index<<1|1]=(tag[index]+ tag[index<<1|1])%mod;
 58     tag[index]=0;
 59 }
 60 
 61 void update(int index,int l,int r,int x,int y,ll k)
 62 {
 63     if (x<=l && r<=y)
 64     {
 65         sum[index]=(k*(r-l+1) +sum[index])%mod;
 66         tag[index]=(k +tag[index])%mod;
 67         return;
 68     }
 69     int m=(l+r)>>1;
 70     if (tag[index]!=0)
 71         pushdown(index,r-l+1);
 72     if (x<=m)
 73         update(index<<1,l,m,x,y,k);
 74     if (m<y)
 75         update(index<<1|1,m+1,r,x,y,k);
 76     sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
 77 }
 78 
 79 ll query(int index,int l,int r,int x,int y)
 80 {
 81     if (x<=l && r<=y)
 82         return sum[index];
 83     if (r<x || l>y)
 84         return 0;
 85     if (tag[index]!=0)
 86         pushdown(index,r-l+1);
 87     int m=(l+r)>>1;
 88     return (query(index<<1,l,m,x,y)+query(index<<1|1,m+1,r,x,y))%mod;
 89 }
 90 
 91 int main()
 92 {
 93     int n,m,mode,x,y;
 94     ll k;
 95     scanf("%d%d",&n,&m);
 96     build(1,1,n);
 97     while (m--)
 98     {
 99         scanf("%d",&mode);
100         if (mode==1)
101         {
102             scanf("%d%d%lld",&x,&y,&k);
103             update(1,1,n,x,y,k%mod);
104         }
105         else
106         {
107             scanf("%d%d",&x,&y);
108             printf("%lld\n",query(1,1,n,x,y));
109         }
110     }
111     return 0;
112 }
113 /*
114 10
115 463 793 740 374 330 772 681
116 5 8 39
117 5 8
118 3 6 3
119 5 8 90
120 1 5 21
121 3 8
122 3 8 17
123 4 7 52
124 2 6
125 2 7 41
126 5
127 2 3 4 5
128 1 3 -1
129 1 3 1
130 2 4
131 100
132 2 3 4 5 6 7 8 9 10
133 1 10
134 2 7 1
135 1 10
136 3 8
137 
138 */

3.

https://www.luogu.org/problemnew/show/P3373

  1 /*
  2 1.將某區間每一個數乘上x
  3 
  4 2.將某區間每一個數加上x
  5 
  6 3.求出某區間每一個數的和
  7 */
  8 #include <cstdio>
  9 #include <cstdlib>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <time.h>
 13 #include <string>
 14 #include <set>
 15 #include <map>
 16 #include <list>
 17 #include <stack>
 18 #include <queue>
 19 #include <vector>
 20 #include <bitset>
 21 #include <ext/rope>
 22 #include <algorithm>
 23 #include <iostream>
 24 using namespace std;
 25 #define ll long long
 26 #define minv 1e-6
 27 #define inf 1e9
 28 #define pi 3.1415926536
 29 #define E  2.7182818284
 30 //const ll mod=1e9+7;//998244353
 31 const int maxn=1e5+10;
 32 
 33 ll mod;
 34 ll add[maxn<<2],mul[maxn<<2],sum[maxn<<2];
 35 int mode;
 36 
 37 void build(int index,int l,int r)
 38 {
 39     add[index]=0;
 40     mul[index]=1;
 41     if (l==r)
 42     {
 43         scanf("%lld",&sum[index]);
 44         sum[index]=sum[index]%mod;
 45     }
 46     else
 47     {
 48         int m=(l+r)>>1;
 49         build(index<<1,l,m);
 50         build(index<<1|1,m+1,r);
 51         sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
 52     }
 53 }
 54 
 55 void pushdown(int index,ll len)
 56 {
 57     //(x *y+z)*s+t = x*(ys) + z*s+t
 58     add[index<<1]=(add[index<<1]*mul[index]+add[index])%mod;
 59     mul[index<<1]=mul[index]*mul[index<<1]%mod;
 60     sum[index<<1]=(sum[index<<1]*mul[index]+add[index]*((len+1)>>1))%mod;
 61 
 62     add[index<<1|1]=(add[index<<1|1]*mul[index]+add[index])%mod;
 63     mul[index<<1|1]=mul[index]*mul[index<<1|1]%mod;
 64     sum[index<<1|1]=(sum[index<<1|1]*mul[index]+add[index]*(len>>1))%mod;
 65 
 66     add[index]=0;
 67     mul[index]=1;
 68 }
 69 
 70 void update(int index,int l,int r,int x,int y,ll k)
 71 {
 72     if (x<=l && r<=y)
 73     {
 74         if (mode==1)
 75         {
 76             //(x*y+z)*k
 77             sum[index]=sum[index]*k%mod;
 78             add[index]=add[index]*k%mod;
 79             mul[index]=mul[index]*k%mod;
 80         }
 81         else
 82         {
 83             //(x*y+z)+k
 84             sum[index]=(sum[index]+k*(r-l+1))%mod;
 85             add[index]=(add[index]+k)%mod;
 86         }
 87         return;
 88     }
 89     pushdown(index,r-l+1);
 90     int m=(l+r)>>1;
 91     if (x<=m)
 92         update(index<<1,l,m,x,y,k);
 93     if (m<y)
 94         update(index<<1|1,m+1,r,x,y,k);
 95     sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
 96 }
 97 
 98 ll query(int index,int l,int r,int x,int y)
 99 {
100     if (x<=l && r<=y)
101         return sum[index];
102     if (x>r || y<l)
103         return 0;
104     pushdown(index,r-l+1);
105     int m=(l+r)>>1;
106     return (query(index<<1,l,m,x,y)+query(index<<1|1,m+1,r,x,y))%mod;
107 }
108 
109 int main()
110 {
111     int n,q,x,y;
112     ll k;
113     scanf("%d%d%lld",&n,&q,&mod);
114     build(1,1,n);
115     while (q--)
116     {
117         scanf("%d%d%d",&mode,&x,&y);
118         if (mode!=3)
119         {
120             scanf("%lld",&k);
121             update(1,1,n,x,y,k%mod);
122         }
123         else
124             printf("%lld\n",query(1,1,n,x,y));
125     }
126     return 0;
127 }
128 /*
129 5 100 1000000
130 1 2 3 4 5
131 1 1 5 2
132 2 1 5 3
133 3 1 3
134 
135 */

線段樹區間更新 lazy