线段树
题目大意:一个线段树支持下面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 }