线段树模板

简单版本:

  1 #include <bits/stdc++.h>
  2 #define pi acos(-1)
  3 using namespace std;
  4 typedef long long LL;
  5 typedef pair<int, int> P;
  6 const int INF = 0x3f3f3f3f;
  7 const LL ll_INF = 0x3f3f3f3f3f3f3f3f;
  8 const int MAXN = 1e5 + 10;
  9 const int mod = 1e9 + 7;
 10 
 11 #define maxn 100007  //元素总个数
 12 #define ls l,m,rt<<1
 13 #define rs m+1,r,rt<<1|1
 14 LL sum[maxn<<2], add[maxn<<2];
 15 LL a[maxn];
 16 int n, m;
 17 
 18 void PushUp(int rt) { sum[rt] = sum[rt<<1]+sum[rt<<1|1]; }
 19 void PushDown(int rt, int ln, int rn)
 20 {
 21     if(add[rt]){
 22         add[rt<<1] += add[rt];
 23         add[rt<<1|1] += add[rt];
 24         sum[rt<<1] += add[rt]*ln;
 25         sum[rt<<1|1] += add[rt]*rn;
 26         add[rt]=0;
 27     }
 28 }
 29 void Build(int l, int r, int rt)
 30 {
 31     if(l==r){
 32         sum[rt]=a[l];
 33         return;
 34     }
 35     int mid = (l+r)>>1;
 36     Build(l, mid, rt<<1);
 37     Build(mid+1, r, rt<<1|1);
 38     PushUp(rt);
 39 }
 40 
 41 //点的更新,假设A[L]+=C
 42 void update(int L, LL C, int l, int r, int rt)
 43 {
 44     if(l==r){
 45         sum[rt]+=C;
 46         return;
 47     }
 48     int mid = (l+r)>>1;
 49     PushDown(rt, mid-l+1, r-mid);
 50     if(L <= mid) update(L, C, l, mid, rt<<1);
 51     else         update(L, C, mid+1, r, rt<<1|1);
 52     PushUp(rt);
 53 }
 54 
 55 //区间更新,假设A[L,R]+=C
 56 void update(int L, int R, LL C, int l, int r, int rt)
 57 {
 58     if(L<=l && r<=R){
 59         sum[rt]+=C*(r-l+1);
 60         add[rt]+=C;
 61         return ;
 62     }
 63     int mid = (l+r)>>1;
 64     PushDown(rt, mid-l+1, r-mid);
 65     if(L <= mid) update(L, R, C, l, mid, rt<<1);
 66     if(R >  mid) update(L, R, C, mid+1, r, rt<<1|1);
 67     PushUp(rt);
 68 }
 69 
 70 //区间查询
 71 LL Query(int L, int R, int l, int r, int rt)
 72 {
 73     if(L<=l && r<=R){
 74         return sum[rt];
 75     }
 76     int mid = (l+r)>>1;
 77     PushDown(rt, mid-l+1, r-mid);
 78     LL ans=0;
 79     if(L<=mid) ans += Query(L, R, l, mid, rt<<1);
 80     if(R> mid) ans += Query(L, R, mid+1, r, rt<<1|1);
 81     return ans;
 82 }
 83 
 84 int main()
 85 {
 86     scanf("%d%d", &n, &m);
 87     int flag, x, y;
 88     LL k;
 89     for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
 90     Build(1, n, 1);
 91     for(int i=1; i<=m; i++) {
 92         scanf("%d", &flag);
 93         if(flag==1){
 94             scanf("%d%d%lld", &x, &y, &k);
 95             update(x, y, k, 1, n, 1);
 96         }
 97         else if(flag==2){
 98             scanf("%d%d", &x, &y);
 99             printf("%lld\n", Query(x, y, 1, n, 1));
100         }
101     }
102 }

 

复杂版本(带lazy)

  1 #include <bits/stdc++.h>
  2 #define pi acos(-1)
  3 using namespace std;
  4 typedef long long LL;
  5 typedef pair<int, int> P;
  6 const int INF = 0x3f3f3f3f;
  7 const LL ll_INF = 0x3f3f3f3f3f3f3f3f;
  8 const int MAXN = 1e5 + 10;
  9 const int mod = 1e9 + 7;
 10 
 11 #define ls l,m,rt<<1
 12 #define rs m+1,r,rt<<1|1
 13 LL sum[MAXN<<2], add[MAXN<<2], mul[MAXN<<2];
 14 LL a[MAXN];
 15 LL n, m, p;
 16 struct LazyTag
 17 {
 18     int mul, add, res;
 19 }lz[MAXN<<2];
 20 
 21 void PushUp(int rt) { sum[rt] = ( sum[rt<<1]+sum[rt<<1|1] )%p; }
 22 void PushDown(int rt, int ln, int rn)
 23 {
 24     sum[rt<<1] = ( sum[rt<<1]*mul[rt] + add[rt]*ln )%p;
 25     sum[rt<<1|1] = ( sum[rt<<1|1]*mul[rt] + add[rt]*rn )%p;
 26 
 27     mul[rt<<1] = ( mul[rt<<1]*mul[rt] )%p;
 28     mul[rt<<1|1] = ( mul[rt<<1|1]*mul[rt] )%p;
 29 
 30     add[rt<<1] = ( add[rt<<1]*mul[rt] + add[rt] )%p;
 31     add[rt<<1|1] = ( add[rt<<1|1]*mul[rt] + add[rt] )%p;
 32 
 33     mul[rt]=1;
 34     add[rt]=0;
 35     return ;
 36 }
 37 
 38 void Build(int l, int r, int rt)
 39 {
 40     mul[rt]=1;
 41     add[rt]=0;
 42     if(l==r){
 43         sum[rt]=a[l];
 44         return;
 45     }
 46     int mid = (l+r)>>1;
 47     Build(l, mid, rt<<1);
 48     Build(mid+1, r, rt<<1|1);
 49     PushUp(rt);
 50 }
 51 
 52 //点的更新,假设A[L]+=C
 53 void update_plus(int L, LL C, int l, int r, int rt)
 54 {
 55     if(l==r){
 56         sum[rt]+=C;
 57         return;
 58     }
 59     int mid = (l+r)>>1;
 60     PushDown(rt, mid-l+1, r-mid);
 61     if(L <= mid) update_plus(L, C, l, mid, rt<<1);
 62     else         update_plus(L, C, mid+1, r, rt<<1|1);
 63     PushUp(rt);
 64 }
 65 
 66 //区间更新,假设A[L,R]+=C
 67 void update_plus(int L, int R, LL C, int l, int r, int rt)
 68 {
 69     if(L<=l && r<=R){
 70         sum[rt] = ( sum[rt] + C*(r-l+1) )%p;
 71         add[rt] = ( add[rt] + C )%p ;
 72         return ;
 73     }
 74     int mid = (l+r)>>1;
 75     PushDown(rt, mid-l+1, r-mid);
 76     if(L <= mid) update_plus(L, R, C, l, mid, rt<<1);
 77     if(R >  mid) update_plus(L, R, C, mid+1, r, rt<<1|1);
 78     PushUp(rt);
 79 }
 80 
 81 void update_mutiple(int L, int R, LL k, int l, int r, int rt)
 82 {
 83     if(L<=l && r<=R){
 84         sum[rt] = ( sum[rt]*k )%p;
 85         mul[rt] = ( mul[rt]*k )%p;
 86         add[rt] = ( add[rt]*k )%p;
 87         return ;
 88     }
 89     int mid = (l+r)>>1;
 90     PushDown(rt, mid-l+1, r-mid);
 91     if(L <= mid) update_mutiple(L, R, k, l, mid, rt<<1);
 92     if(R >  mid) update_mutiple(L, R, k, mid+1, r, rt<<1|1);
 93     PushUp(rt);
 94 }
 95 
 96 //区间查询
 97 LL Query(int L, int R, int l, int r, int rt)
 98 {
 99     if(L<=l && r<=R){
100         return sum[rt];
101     }
102     int mid = (l+r)>>1;
103     PushDown(rt, mid-l+1, r-mid);
104     LL ans=0;
105     if(L<=mid) ans = ( ans + Query(L, R, l, mid, rt<<1) )%p ;
106     if(R> mid) ans = ( ans + Query(L, R, mid+1, r, rt<<1|1) )%p;
107     return ans;
108 }
109 
110 int main()
111 {
112     cin >> n >> m >> p;
113     for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
114     Build(1, n, 1);
115     int flag, x, y;
116     LL k;
117     for(int i=1; i<=m; i++){
118         scanf("%d%d%d", &flag, &x, &y);
119         if(flag==1){
120             scanf("%lld", &k);
121             update_mutiple(x, y, k, 1, n, 1);
122         }
123         else if(flag==2){
124             scanf("%lld", &k);
125             update_plus(x, y, k, 1, n, 1);
126         }
127         else if(flag==3){
128             printf("%lld\n", Query(x, y, 1, n, 1) );
129         }
130     }
131     return 0;
132 }

 

posted @ 2018-08-22 17:44  会打架的程序员不是好客服  阅读(246)  评论(0编辑  收藏  举报