线段树

题目大意:一个线段树支持下面4中操作。

1.对于一个区间[l,r]把区间中的每个元素加c;

2.对于一个区间[l,r]把区间中的每个元素减c;

3.对于一个区间[l,r]把区间中的每个元素置c;

4.对于一个区间[l,r]求区间的和,并把这个和加到列表的每个元素上。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int imax_n = 10005;
  5 const long long PP = 1000000009;
  6 
  7 struct Node
  8 {
  9     int l, r;
 10     long long sum;
 11     long long val;
 12     long long c;
 13     long long s;
 14 }f[8 * imax_n];
 15 
 16 long long a[imax_n];
 17 int n, m;
 18 
 19 void build(int t, int l, int r, long long *a)
 20 {
 21     // printf("build %d %d %d\n", t, l, r);
 22     f[t].l = l;
 23     f[t].r = r;
 24     f[t].val = 0LL;
 25     f[t].c = 0LL;
 26     f[t].s = 0LL;
 27     if (l == r)
 28     {
 29         // printf("add = %d\n", a[l-1]);
 30         f[t].val = a[l-1];
 31         f[t].sum = a[l-1];
 32         // printf("%lld\n", f[t].sum);
 33         return ;
 34     }
 35     int mid = (l + r) / 2;
 36     build(2*t, l , mid, a);
 37     build(2*t+1, mid+1, r, a);
 38     f[t].sum = (f[2*t].sum + f[2*t+1].sum) % PP;
 39 }
 40 
 41 void pushDown(int t)
 42 {
 43     if (f[t].s)
 44     {
 45         f[2*t].s = f[t].s;
 46         f[2*t+1].s = f[t].s;
 47         f[2*t].val = f[t].val;
 48         f[2*t].sum = f[t].val * (f[2*t].r - f[2*t].l + 1) % PP;
 49         f[2*t + 1].val = f[t].val;
 50         f[2*t + 1].sum = f[t].val * (f[2*t + 1].r - f[2*t+1].l + 1) % PP;
 51         f[t].s = 0LL;
 52         f[t].c = 0LL;
 53         f[t].val = 0LL;
 54     }
 55 
 56     if (f[t].c)
 57     {
 58         f[2*t].c = (f[2*t].c + f[t].c) % PP;
 59         f[2*t+1].c  = (f[2*t+1].c + f[t].c) %PP;
 60         f[2*t].sum = (f[2*t].sum + f[t].c * (f[2*t].r - f[2*t].l + 1)) % PP;
 61         f[2*t + 1].sum = (f[2*t+1].sum + f[t].c * (f[2*t+1].r - f[2*t+1].l + 1)) % PP;
 62         f[t].c = 0;
 63     }
 64 }
 65 
 66 void pushUp(int t)
 67 {
 68     f[t].sum = (f[2*t].sum + f[2*t+1].sum) % PP;
 69 }
 70 
 71 void modify(int t, int l, int r, int c)
 72 {
 73     if (f[t].l == l && f[t].r == r)
 74     {
 75         if (f[t].s)
 76             f[t].val = (f[t].val + c) % PP;
 77         else
 78             f[t].c = (f[t].c + c) % PP;
 79         f[t].sum = (f[t].sum + (long long )c * (f[t].r - f[t].l + 1)) % PP;
 80         return ;
 81     }
 82 
 83     pushDown(t);
 84     int mid = (f[t].l + f[t].r) / 2;
 85     if (r<=mid) modify(2*t, l, r, c);
 86     else if (l > mid) modify(2*t+1, l, r, c);
 87     else
 88     {
 89         modify(2*t, l, mid, c);
 90         modify(2*t+1, mid + 1, r, c);
 91     }
 92     pushUp(t);
 93 }
 94 
 95 void set_(int t, int l, int r, int val)
 96 {
 97     // printf("set_ %d %d %d\n", t, l, r);
 98     if (f[t].l == l && f[t].r == r)
 99     {
100         f[t].s = 1LL;
101         f[t].val = (long long )val;
102         f[t].sum = f[t].val* (f[t].r - f[t].l + 1) % PP;
103         return;
104     }
105     pushDown(t);
106     int mid = (f[t].l + f[t].r) / 2;
107     if (r <= mid) set_(2*t, l, r, val);
108     else if (l > mid) set_(2*t+1, l, r, val);
109     else
110     {
111         set_(2*t, l, mid, val);
112         set_(2*t+1, mid+1, r, val);
113     }
114     pushUp(t);
115 }
116 
117 long long query(int t, int l, int r)
118 {
119     if (f[t].l == l && f[t].r == r)
120     {
121         return f[t].sum % PP;
122     }
123     pushDown(t);
124     int mid = (f[t].l + f[t].r) / 2;
125     if (r<=mid) return query(2*t, l, r);
126     else if (l > mid) return query(2*t + 1, l, r);
127     else
128     {
129         return (query(2*t, l, mid) + query(2*t+1, mid+1, r)) % PP;
130     }
131 }
132 
133 void print_tree(int t)
134 {
135     printf("node: %d l=%d r=%d s=%lld c=%lld sum=%lld\n", t, f[t].l, f[t].r, f[t].s, f[t].c, f[t].sum);
136     if (f[t].l == f[t].r)
137     {
138         return;
139     }
140     print_tree(2*t);
141     print_tree(2*t+1);
142 }
143 
144 void dfs(int t, vector<int> &ans)
145 {
146 
147     if (f[t].l == f[t].r)
148     {
149         ans.push_back((int)(f[t].sum%PP));
150         return ;
151     }
152     pushDown(t);
153     dfs(2*t, ans);
154     dfs(2*t+1, ans);
155     pushUp(t);
156 }
157 
158 int main()
159 {
160     scanf("%d%d", &n, &m);
161     for (int i = 0; i < n; ++i)
162     {
163         scanf("%lld", &a[i]);
164     }
165     build(1, 1, n, a);
166     // print_tree(1);
167     long long op4 = 0LL;
168     for (int i = 0; i < m; ++i)
169     {
170         int op, x, y, c;
171         scanf("%d%d%d%d", &op, &x, &y, &c);
172         if (op==1)
173         {
174             modify(1, x, y, c);
175             // print_tree(1);
176         }
177         else if (op==2)
178         {
179             modify(1, x, y, -c);
180             // print_tree(1);
181         }
182         else if (op==3)
183         {
184             set_(1, x, y, c);
185             // print_tree(1);
186         }
187         else
188         {
189             op4 = query(1, x, y) % PP;
190             // printf("qeury %d %d op4 = %lld\n", x, y, op4);
191             modify(1, 1, n, op4);
192         }
193     }
194     vector<int> ans;
195     dfs(1, ans);
196     for (int i = 0; i < ans.size(); ++i)
197     {
198         printf("%d ", ans[i]);
199     }
200     printf("\n");
201     return 0;
202 }

 

posted @ 2018-04-03 18:57  只会一点暴力  阅读(188)  评论(0编辑  收藏  举报