[kuangbin]带你飞之'线段树'专题

// 带飞网址 https://vjudge.net/article/187

专题七 线段树 
√ HDU 1166 敌兵布阵
√ HDU 1754 I Hate It
√ POJ 3468 A Simple Problem with Integers
√ POJ 2528 Mayor's posters
√ HDU 1698 Just a Hook
ZOJ 1610 Count the Colors
√ POJ 3264 Balanced Lineup
√ HDU 4027 Can you answer these queries?
√ HDU 1540 Tunnel Warfare
√ HDU 3974 Assign the task
√ HDU 4578 Transformation
√ HDU 4614 Vases and Flowers
HDU 4553 约会安排
√ POJ 1177 Picture
√ HDU 1255 覆盖的面积
√ HDU 1542 Atlantis
HDU 3642 Get The Treasury

 // hdu 4614 简单线段树+二分

  1 /*
  2  * @Promlem: 
  3  * @Time Limit: ms
  4  * @Memory Limit: k
  5  * @Author: pupil-XJ
  6  * @Date: 2019-10-12 14:11:16
  7  * @LastEditTime: 2019-10-13 11:47:17
  8  */
  9 #include<cstdio>
 10 #include<algorithm>
 11 #define L k<<1
 12 #define R k<<1|1
 13 #define mid (tree[k].l+tree[k].r)>>1
 14 using namespace std;
 15 const int MAXN = 50000+5;
 16 
 17 struct segmemt_tree {
 18     int l, r;
 19     int num, f;
 20 } tree[4*MAXN+1];
 21 
 22 void build(int k, int l, int r) {
 23     tree[k].l = l; tree[k].r = r;
 24     tree[k].num = 0;
 25     tree[k].f = -1;
 26     if(l == r) return ;
 27     int m = mid;
 28     build(L, l, m);
 29     build(R, m+1, r);
 30 }
 31 
 32 void push_down(int k) {
 33     tree[L].f = tree[R].f = tree[k].f;
 34     int m = mid;
 35     tree[L].num = (m-tree[k].l+1) * tree[k].f;
 36     tree[R].num = (tree[k].r-m) * tree[k].f;
 37     tree[k].f = -1;
 38 }
 39 
 40 int query(int k, int x, int y) {
 41     if(tree[k].l >= x && tree[k].r <= y) return tree[k].num;
 42     if(tree[k].f != -1) push_down(k);
 43     int m = mid;
 44     int ans = 0;
 45     if(x <= m) ans = query(L, x, y);
 46     if(y > m) ans += query(R, x, y);
 47     return ans;
 48 }
 49 
 50 int bin(int start, int end, int cnt) {
 51     int l = start, r = end;
 52     while(l < r) {
 53         int m = (l + r) / 2;
 54         int t = (m - start + 1) - query(1, start, m);
 55         if(t >= cnt) r = m;
 56         else l = m + 1;
 57     }
 58     return l;
 59 }
 60 
 61 void change(int k, int x, int y, int v) {
 62     if(tree[k].l >= x && tree[k].r <= y) {
 63         tree[k].f = v;
 64         tree[k].num = (tree[k].r - tree[k].l + 1) * v;
 65         return ;
 66     }
 67     if(tree[k].f != -1) push_down(k);
 68     int m = mid;
 69     if(x <= m) change(L, x, y, v);
 70     if(y > m) change(R, x, y, v);
 71     tree[k].num = tree[L].num + tree[R].num;
 72 }
 73 
 74 int main() {
 75     int T;
 76     scanf("%d", &T);
 77     while(T--) {
 78         int n, m;
 79         scanf("%d%d", &n, &m);
 80         build(1, 0, n-1);
 81         int op, x, y;
 82         int s, e;
 83         for(int i = 0; i != m; ++i) {
 84             scanf("%d%d%d", &op, &x, &y);
 85             if(op == 1) {
 86                 int one = query(1, x, n-1);
 87                 if(one == n-1-x+1) printf("Can not put any one.
");
 88                 else {
 89                     s = bin(x, n-1, 1);
 90                     e = bin(s, n-1, min(n-1-x+1-one, y));
 91                     printf("%d %d
", s, e);
 92                     change(1, s, e, 1);
 93                 }
 94             }
 95             else printf("%d
", query(1, x, y)), change(1, x, y, 0);
 96         }
 97         printf("
");
 98     }
 99     return 0;
100 }
View Code

// poj 2528 离散化思想

 1 #include<cstdio>
 2 #include<vector>
 3 #include<set>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int MAXN = 10000+5;
 8 
 9 struct segmemt_tree {
10     int l, r, w;
11 } tree[MAXN*2*2*2*2];
12 
13 int l[2*MAXN], r[2*MAXN];
14 set<int> ct;
15 
16 inline void build(int k, int l, int r) {
17     tree[k].l = l; tree[k].r = r;
18     if(tree[k]. l == tree[k].r) {
19         tree[k].w = 0;
20         return ;
21     }
22     int m = (l + r) / 2;
23     build(k*2, l, m);
24     build(k*2+1, m+1, r);
25     tree[k].w = 0;
26 }
27 
28 inline void down(int k) {
29     tree[k*2].w = tree[k*2+1].w = tree[k].w;
30     tree[k].w = 0;
31 }
32 
33 inline void change_interval(int k, int x, int y, int v) {
34     if(tree[k].l >= x && tree[k].r <= y) {
35         tree[k].w = v;
36         return ;
37     }
38     if(tree[k].w) down(k);
39     int m = (tree[k].l + tree[k].r) / 2;
40     if(x <= m) change_interval(k*2, x, y, v);
41     if(y > m) change_interval(k*2+1, x, y, v);
42 }
43 
44 inline void query_interval(int k, int x, int y) {
45     if(tree[k].l == tree[k].r && !tree[k].w) return ;
46     if(tree[k].l >= x && tree[k].r <= y && tree[k].w) {
47         ct.insert(tree[k].w);
48         return ;
49     }
50     int m = (tree[k].l + tree[k].r) / 2;
51     if(x <= m) query_interval(k*2, x, y);
52     if(y > m) query_interval(k*2+1, x, y);
53 }
54 
55 int main() {
56     int T, n;
57     scanf("%d", &T);
58     while(T--) {
59         vector<int> v;
60         scanf("%d", &n);
61         for(int i = 1; i <= n; ++i) {
62             scanf("%d%d", &l[i], &r[i]);
63             v.push_back(l[i]);
64             v.push_back(r[i]);
65         }
66         sort(v.begin(), v.end());
67         v.erase(unique(v.begin(), v.end()), v.end());
68         int a[2*MAXN];
69         a[0] = 1;
70         int cnt = 1;
71         for(int i = 1; i != v.size(); ++i) {
72             if(v[i] == v[i-1]+1) {
73                 ++cnt;
74                 a[i] = cnt;
75             }
76             else {
77                 cnt += 2;
78                 a[i] = cnt;
79             }
80         }
81         build(1, 1, v.size()*2+5);
82 
83         int x, y;
84         for(int i = 1; i <= n; ++i) {
85             x = a[lower_bound(v.begin(), v.end(), l[i]) - v.begin()];
86             y = a[lower_bound(v.begin(), v.end(), r[i]) - v.begin()];
87             change_interval(1, x, y, i);
88         }
89 
90         ct.clear();
91         query_interval(1, 1, v.size()*2+5);
92         printf("%d
", ct.size());
93     }
94     return 0;
95 }
View Code

// hdu 1542 线扫瞄+离散化线段树(覆盖面积)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define L k<<1
 4 #define R k<<1|1
 5 #define mid (tree[k].l+tree[k].r)>>1
 6 using namespace std;
 7 typedef long long ll;
 8 const int MAXN = 200+5;
 9 
10 double X[MAXN];
11 struct Edge {
12     double l, r;
13     double h;
14     int f;
15     Edge() {}
16     Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f) {}
17     bool operator < (const Edge &a) const {
18         return h < a.h;
19     }
20 }edge[MAXN];
21 //Edge ;
22 
23 struct segmemt_tree {
24     int l, r;// 左右区间端点
25     int cover;
26     double len;
27 }tree[4*MAXN+1];
28 
29 inline void build(int k, int l, int r) {
30     tree[k].l = l; tree[k].r = r;
31     tree[k].cover = tree[k].len = 0;
32     if(l == r) return ;
33     int m = mid;
34     build(L, l, m);
35     build(R, m+1, r);
36 }
37 
38 inline void push_up(int k) {
39     if(tree[k].cover) tree[k].len = X[tree[k].r+1] - X[tree[k].l];
40     else if(tree[k].l == tree[k].r) tree[k].len = 0;
41     else tree[k].len = tree[L].len + tree[R].len;
42 }
43 
44 inline void update(int k, int x, int y, int cover) {
45     if(tree[k].l >= x && tree[k].r <= y) {
46         tree[k].cover += cover;
47         push_up(k);
48         return ;
49     }
50     int m = mid;
51     if(x <= m) update(L, x, y, cover);
52     if(y > m) update(R, x, y, cover);
53     push_up(k);
54 }
55 
56 int main() {
57     int n, Case = 0;
58     while(scanf("%d", &n) == 1 && n) {
59         int cnt = 0;
60         double x1, y1, x2, y2;
61         for(int i = 0; i != n; ++i) {
62             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
63             X[cnt] = x1;
64             edge[cnt++] = Edge(x1, x2, y1, 1);
65             X[cnt] = x2;
66             edge[cnt++] = Edge(x1, x2, y2, -1);
67         }
68         sort(X, X+cnt);
69         sort(edge, edge+cnt);
70         int k = unique(X, X+cnt) - X;
71         build(1, 0, k-1);
72         double sum = 0;
73         for(int i = 0; i != cnt; ++i) {
74             int l = lower_bound(X, X+k, edge[i].l) - X;
75             int r = lower_bound(X, X+k, edge[i].r) - X - 1;
76             update(1, l, r, edge[i].f);
77             sum += (edge[i+1].h - edge[i].h) * tree[1].len;
78         }
79         printf("Test case #%d
", ++Case);
80         printf("Total explored area: %.2lf

", sum);
81     }
82     return 0;
83 }
View Code

// hud 1255

 1 /*
 2  * @Author: pupil-XJ
 3  * @Date: 2019-10-10 00:09:46
 4  * @LastEditTime: 2019-10-10 11:47:20
 5  */
 6 #include<cstdio>
 7 #include<algorithm>
 8 #define L k<<1
 9 #define R k<<1|1
10 #define mid (tree[k].l+tree[k].r)>>1
11 using namespace std;
12 const int MAXN = 2000+5;
13 
14 double x[MAXN];
15 struct Edge {
16     double l, r, h;
17     int f;
18     Edge(){}
19     Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f){}
20     bool operator < (const Edge &a) const {
21         return h < a.h;
22     }
23 } edge[MAXN];
24 
25 struct segmemt_tree {
26     int l, r, cover;
27     double len1, len2;// len1(cover once) len2(cover over than once)
28 } tree[4*MAXN+1];
29 
30 inline void build(int k, int l, int r) {
31     tree[k].l = l; tree[k].r = r;
32     tree[k].cover = tree[k].len1 = tree[k].len2 = 0;
33     if(l == r) return ;
34     int m = mid;
35     build(L, l, m);
36     build(R, m+1, r);
37 }
38 
39 inline void push_up(int k) {
40     // update->len1
41     if(tree[k].cover) tree[k].len1 = x[tree[k].r+1] - x[tree[k].l];
42     else if(tree[k].l == tree[k].r) tree[k].len1 = 0;
43     else tree[k].len1 = tree[L].len1 + tree[R].len1;
44     // update->len2
45     if(tree[k].cover > 1) tree[k].len2 = x[tree[k].r+1] - x[tree[k].l];
46     else if(tree[k].l == tree[k].r) tree[k].len2 = 0;
47     else if(tree[k].cover == 1) tree[k].len2 = tree[L].len1 + tree[R].len1;
48     else tree[k].len2 = tree[L].len2 + tree[R].len2;
49 }
50 
51 inline void update(int k, int x, int y, int f) {
52     if(tree[k].l >= x && tree[k].r <= y) {
53         tree[k].cover += f;
54         push_up(k);
55         return ;
56     }
57     int m = mid;
58     if(x <= m) update(L, x, y, f);
59     if(y > m) update(R, x, y, f);
60     push_up(k);
61 }
62 
63 int main() {
64     int T, n;
65     double x1, y1, x2, y2;
66     scanf("%d", &T);
67     while(T--) {
68         scanf("%d", &n);
69         int cnt = 0;
70         for(int i = 0; i != n; ++i) {
71             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
72             x[cnt] = x1;
73             edge[cnt++] = Edge(x1, x2, y1, 1);
74             x[cnt] = x2;
75             edge[cnt++] = Edge(x1, x2, y2, -1);
76         }
77         sort(x, x+cnt);
78         sort(edge, edge+cnt);
79         int k = unique(x, x+cnt) - x;
80         
81         build(1, 0, k-1);
82         double sum = 0;
83         for(int i = 0; i != cnt; ++i) {
84             int l = lower_bound(x, x+k, edge[i].l) - x;
85             int r = lower_bound(x, x+k, edge[i].r) - x - 1;
86             update(1, l, r, edge[i].f);
87             sum += (edge[i+1].h - edge[i].h) * tree[1].len2;
88         }
89         printf("%.2lf
", sum);
90     }
91     return 0;
92 }
View Code

// poj 1177 线扫瞄+离散化线段树(覆盖周长)

 1 /*
 2  * @Author: pupil-XJ
 3  * @Date: 2019-10-11 01:10:10
 4  * @LastEditTime: 2019-10-11 20:55:44
 5  */
 6 #include<cstdio>
 7 #include<cmath>
 8 #include<algorithm>
 9 #define L k<<1
10 #define R k<<1|1
11 #define mid (tree[k].l+tree[k].r)>>1
12 using namespace std;
13 const int MAXN = 10000+5;
14 
15 int x[MAXN];
16 struct Edge {
17     int l, r, h;
18     int f;
19     Edge(){}
20     Edge(int l, int r, int h, int f):l(l),r(r),h(h),f(f){}
21     bool operator < (const Edge &a) const {
22         return h < a.h;
23     }
24 } edge[MAXN];
25 
26 struct segmemt_tree {
27     int l, r, cover, num;
28     int lc, rc;
29     int len;
30 } tree[4*MAXN+1];
31 
32 inline void build(int k, int l, int r) {
33     tree[k].l = l; tree[k].r = r;
34     tree[k].cover = tree[k].num = tree[k].lc = tree[k].rc = tree[k].len = 0;
35     if(l == r) return;
36     int m = mid;
37     build(L, l, m);
38     build(R, m+1, r);
39 }
40 
41 inline void push_up(int k) {
42     if(tree[k].cover) {
43         tree[k].len = x[tree[k].r+1] - x[tree[k].l];
44         tree[k].lc = tree[k].rc = 1;
45         tree[k].num = 1;
46     }
47     else if(tree[k].l == tree[k].r) {
48         tree[k].len = 0;
49         tree[k].lc = tree[k].rc = 0;
50         tree[k].num = 0;
51     }
52     else {
53         tree[k].len = tree[L].len + tree[R].len;
54         tree[k].lc = tree[L].lc; tree[k].rc = tree[R].rc;
55         tree[k].num = tree[L].num + tree[R].num - (tree[L].rc&tree[R].lc);
56     }
57 }
58 
59 inline void update(int k, int x, int y, int f) {
60     if(tree[k].l >= x && tree[k].r <= y) {
61         tree[k].cover += f;
62         push_up(k);
63         return ;
64     }
65     int m = mid;
66     if(x <= m) update(L, x, y, f);
67     if(y > m) update(R, x, y, f);
68     push_up(k);
69 }
70 
71 int main() {
72     int n, cnt = 0;
73     scanf("%d", &n);
74     int x1, x2, y1, y2;
75     for(int i = 0; i != n; ++i) {
76         scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
77         x[cnt] = x1;
78         edge[cnt++] = Edge(x1, x2, y1, 1);
79         x[cnt] = x2;
80         edge[cnt++] = Edge(x1, x2, y2, -1);
81     }
82     sort(x, x+cnt);
83     sort(edge, edge+cnt);
84     int k = unique(x, x+cnt) - x;
85 
86     build(1, 0, k-1);
87     int sum = 0, last = 0;
88     for(int i = 0; i != cnt; ++i) {
89         int l = lower_bound(x, x+k, edge[i].l) - x;
90         int r = lower_bound(x, x+k, edge[i].r) - x - 1;
91         update(1, l, r, edge[i].f);
92         sum += abs(tree[1].len - last);
93         sum += (edge[i+1].h - edge[i].h)*2*tree[1].num;
94         last = tree[1].len;
95     }
96     printf("%d
", sum);
97     return 0;
98 }
View Code

// hdu 3974 通过dfs序建线段树

 1 #include<cstdio>
 2 #include<vector>
 3 using namespace std;
 4 
 5 const int MAXN = 50000+5;
 6 
 7 struct segmemt {
 8     int l, r, w;// w表示当前任务(起始为-1)
 9     int f;
10 } tree[4*MAXN+1];
11 
12 vector<int> G[MAXN];
13 int out[MAXN];
14 int num;// dfs序的时间戳
15 int s[MAXN], e[MAXN];// 点x在线段树区间的两端点标号。s[x]~~e[x]内的值都是他的下属
16 
17 inline void dfs(int x) {
18     s[x] = ++num;
19     int sz = G[x].size();
20     for(int i = 0; i != sz; ++i) dfs(G[x][i]);
21     e[x] = ++num;
22 }
23 
24 inline void build(int k, int l, int r) {
25     tree[k].l = l, tree[k].r = r;
26     tree[k].w = -1;
27     tree[k].f = 0;
28     if(l == r) return ;
29     int m = (l + r) >> 1;
30     build(k<<1, l, m);
31     build(k<<1|1, m+1, r);
32 }
33 
34 inline void down(int k) {
35     tree[k<<1].w = tree[k<<1|1].w = tree[k].w;
36     tree[k<<1].f = tree[k<<1|1].f = 1;
37     tree[k].f = 0;
38 }
39 
40 inline void change_interval(int k, int x, int y, int v) {
41     if(tree[k].l >= x && tree[k].r <= y) {
42         tree[k].w = v; tree[k].f = 1;
43         return;
44     }
45     if(tree[k].f) down(k);
46     int m = (tree[k].l+tree[k].r)>>1;
47     if(x <= m) change_interval(k<<1, x, y, v);
48     if(y > m) change_interval(k<<1|1, x, y, v);
49 }
50 
51 inline int query_point(int k, int x) {
52     if(tree[k].l == tree[k].r) return tree[k].w;
53     if(tree[k].f) down(k);
54     int m = (tree[k].l+tree[k].r)>>1;
55     if(x <= m) return query_point(k<<1, x);
56     else return query_point(k<<1|1, x);
57 }
58 
59 int main() {
60     int T, cnt = 1;
61     scanf("%d", &T);
62     int n, m;
63     int x, y;
64     char com[10];
65     while(T--) {
66         scanf("%d", &n);
67         for(int i = 1; i <= n; ++i) out[i] = 0, G[i].clear();
68         for(int i = 0; i != n-1; ++i) {
69             scanf("%d%d", &x, &y);
70             out[x] = 1;
71             G[y].push_back(x);
72         }
73         num = 0;
74         for(int i = 1; i <= n; ++i) {
75             if(!out[i]) { dfs(i); break; }
76         }
77         build(1, 1, num);
78         scanf("%d", &m);
79         printf("Case #%d:
", cnt++);
80         for(int i = 0; i != m; ++i) {
81             scanf("%s", com);
82             if(com[0] == 'T') {
83                 scanf("%d%d", &x, &y);
84                 change_interval(1, s[x], e[x], y);
85             }
86             else scanf("%d", &x), printf("%d
", query_point(1, s[x]));
87         }
88     }
89     return 0;
90 }
View Code

 // hdu 1540 区间合并 求最大连续区间

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define L k<<1
 4 #define R k<<1|1
 5 #define mid (tree[k].l+tree[k].r)>>1
 6 using namespace std;
 7 
 8 const int MAXN = 50000+5;
 9 
10 int n, m;
11 struct sgmemt_tree {
12     int l, r;
13     int ll, rl;// 此区间最左边得连续区间长度 和 最右边的连续区间的长度
14     int ml;// 此区间最大连续区间长度
15 } tree[4*MAXN+1];
16 
17 inline void build(int k, int l, int r) {
18     tree[k].l = l; tree[k].r = r;
19     tree[k].ll = tree[k].rl = tree[k].ml = r - l + 1;
20     if(l == r) return;
21     int m = (l + r) / 2;
22     build(L, l, m);
23     build(R, m+1, r);
24 }
25 
26 inline void update(int k, int x, int cnt) {
27     if(tree[k].l == tree[k].r) {
28         tree[k].ll = tree[k].rl = tree[k].ml = cnt;
29         return ;
30     }
31     int m = (tree[k].l+tree[k].r)>>1;
32     if(x <= m) update(L, x, cnt);
33     else update(R, x, cnt);
34     // ml
35     tree[k].ml = max(tree[L].ml, tree[R].ml);
36     tree[k].ml = max(tree[k].ml, tree[L].rl + tree[R].ll);
37     // ll
38     tree[k].ll = tree[L].ll == tree[L].r-tree[L].l+1 ? tree[L].ll+tree[R].ll : tree[L].ll;
39     // r;
40     tree[k].rl = tree[R].rl == tree[R].r-tree[R].l+1 ? tree[R].rl+tree[L].rl : tree[R].rl;
41 }
42 
43 inline int query(int k, int x) {
44     if(tree[k].l==tree[k].r || tree[k].ml==0 || tree[k].r-tree[k].l+1==tree[k].ml) return tree[k].ml;
45     int m = (tree[k].l+tree[k].r)>>1;
46     if(x <= m) {
47         if(x >= m-tree[L].rl+1) return query(L, x) + query(R, m+1);
48         else return query(L, x);
49     }
50     else {
51         if(x <= m+tree[R].ll) return query(L, m) + query(R, x);
52         return query(R, x);
53     }
54 }
55 
56 int main() {
57     char com[10];
58     int x;
59     int stack[MAXN], destroy[MAXN], top;
60     while(~scanf("%d%d", &n, &m)) {
61         top = 0;
62         build(1, 1, n);
63         for(int i = 0; i != m; ++i) {
64             scanf("%s", com);
65             if(com[0] == 'D') {
66                 scanf("%d", &x);
67                 update(1, x, 0);
68                 stack[top++] = x;
69             }
70             else if(com[0] == 'R' && top) {
71                     update(1, stack[--top], 1);
72             }
73             else {
74                 scanf("%d", &x);
75                 printf("%d
", query(1, x));
76             }
77         }
78     }
79     return 0;
80 }
View Code

 // hdu 4578 线段树多种区间操作(深入理解lazy标记的作用)细节(;´༎ຶД༎ຶ`) 基本线段树 恶心区间操作

  1 #include<iostream>
  2 #define L k<<1
  3 #define R k<<1|1
  4 #define mid (tree[k].l+tree[k].r)>>1
  5 using namespace std;
  6 const int MAXN = 100005;
  7 const int MOD = 10007;
  8 typedef long long ll;
  9 
 10 struct segmemt_tree {
 11     int l, r;
 12     int add, mul, same;
 13     ll w1, w2, w3;
 14 } tree[4*MAXN+1];
 15 
 16 inline void build(int k, int l, int r) {
 17     tree[k].l = l; tree[k].r = r;
 18     tree[k].add = tree[k].mul = tree[k].same = 0;
 19     tree[k].w1 = tree[k].w2 = tree[k].w3 = 0;
 20     if(l == r) return ;
 21     int m = mid;
 22     build(L, l, m);
 23     build(R, m+1, r);
 24 }
 25 // the import fun;
 26 // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
 27 inline void fun_add(int k, int c) {
 28     tree[k].add = (tree[k].add + c)%MOD;
 29     int sum1 = tree[k].w1, sum2 = tree[k].w2, sum3 = tree[k].w3;
 30     int len = tree[k].r - tree[k].l + 1;
 31 
 32     int tmp1 = c*len%MOD;
 33     tree[k].w1 = (sum1 + tmp1) % MOD;
 34 
 35     int tmp2 = (2*c%MOD*sum1%MOD + len*c%MOD*c%MOD)%MOD;
 36     tree[k].w2 = (sum2 + tmp2) % MOD;
 37 
 38     int tmp3 = (3*c%MOD*sum2%MOD + 3*c%MOD*c%MOD*sum1%MOD + len*c%MOD*c%MOD*c%MOD)%MOD;
 39     tree[k].w3 = (sum3 + tmp3) % MOD;
 40 }
 41 
 42 inline void fun_mul(int k, int c) {
 43     if(tree[k].mul) tree[k].mul = (tree[k].mul*c)%MOD;
 44     else tree[k].mul = c;
 45     tree[k].add = (tree[k].add*c)%MOD;
 46 
 47     int sum1 = tree[k].w1, sum2 = tree[k].w2, sum3 = tree[k].w3;
 48     tree[k].w1 = c*sum1%MOD;
 49     tree[k].w2 = c%MOD*c%MOD*sum2%MOD;
 50     tree[k].w3 = c%MOD*c%MOD*c%MOD*sum3%MOD;
 51 }
 52 
 53 inline void fun_same(int k, int c) {
 54     tree[k].add = tree[k].mul = 0;
 55     tree[k].same = c;
 56     int len = tree[k].r - tree[k].l + 1;
 57     tree[k].w1 = c*len%MOD;
 58     tree[k].w2 = c*tree[k].w1%MOD;
 59     tree[k].w3 = c*tree[k].w2%MOD;
 60 }
 61 
 62 inline void push_down(int k) {
 63     if(tree[k].same) {
 64         fun_same(L, tree[k].same);
 65         fun_same(R, tree[k].same);
 66         tree[k].same = 0;
 67     }
 68     if(tree[k].mul) {
 69         fun_mul(L, tree[k].mul);
 70         fun_mul(R, tree[k].mul);
 71         tree[k].mul = 0;
 72     }
 73     if(tree[k].add) {
 74         fun_add(L, tree[k].add);
 75         fun_add(R, tree[k].add);
 76         tree[k].add = 0;
 77     }
 78 }
 79 // ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
 80 
 81 inline void push_up(int k) {
 82     tree[k].w1 = (tree[L].w1 + tree[R].w1)%MOD;
 83     tree[k].w2 = (tree[L].w2 + tree[R].w2)%MOD;
 84     tree[k].w3 = (tree[L].w3 + tree[R].w3)%MOD;
 85 }
 86 
 87 inline void update(int k, int x, int y, int c, int op) {
 88     if(tree[k].l >= x && tree[k].r <= y) {
 89         if(op == 1) fun_add(k, c);
 90         if(op == 2) fun_mul(k, c);
 91         if(op == 3) fun_same(k, c);
 92         return ;
 93     }
 94     push_down(k);
 95     int m = mid;
 96     if(x <= m) update(L, x, y, c, op);
 97     if(y > m) update(R, x, y, c, op);
 98     push_up(k);
 99 }
100 
101 inline ll query(int k, int x, int y, int c) {
102     if(tree[k].l >= x && tree[k].r <= y) {
103         if(c == 1) return tree[k].w1;
104         else if(c == 2) return tree[k].w2;
105         else return tree[k].w3;
106     }
107     push_down(k);
108     int m = mid;
109     ll ans = 0;
110     if(x <= m) ans = query(L, x, y, c);
111     if(y > m) ans = (ans + query(R, x, y, c)%MOD)%MOD;
112     return ans;
113 }
114 
115 int main() {
116     ios::sync_with_stdio(false);
117     cin.tie(0); cout.tie(0);
118     int n, m;
119     int op, x, y, c;
120     while(cin >> n >> m && n) {
121         build(1, 1, n);
122         for(int i = 0; i != m; ++i) {
123             cin >> op >> x >> y >> c;
124             if(op != 4) update(1, x, y, c%MOD, op);
125             else cout << query(1, x, y, c) << '
';
126         }
127     }
128     return 0;
129 }
View Code
参考博客 点这里->(✿◕‿◕✿)
做了这题 我感受到了 对区间操作一定得想办法用lazy标记 不然妥妥超时 
比如傻瓜式代码↓↓↓↓↓↓↓↓
 1 #include<cstdio>
 2 #define L k<<1
 3 #define R k<<1|1
 4 #define mid (tree[k].l+tree[k].r)>>1;
 5 using namespace std;
 6 typedef long long ll;
 7 const int MAXN = 100000+5;
 8 const int MOD = 10007;
 9 
10 struct segmemt_tree {
11     int l, r;
12     int w1, w2, w3;
13 } tree[4*MAXN+1];
14 
15 inline void build(int k, int l, int r) {
16     tree[k].l = l; tree[k].r = r;
17     if(l == r) {
18         tree[k].w1 = tree[k].w2 = tree[k].w3 = 0;
19         return ;
20     }
21     int m = mid;
22     build(L, l, m);
23     build(R, m+1, r);
24     tree[k].w1 = tree[k].w2 = tree[k].w3 = 0;
25 }
26 
27 inline void change_interval(int k, int x, int y, int v, int com) {
28     if(tree[k].l >= x && tree[k].r <= y) {
29         if(tree[k].l == tree[k].r) {
30             if(com == 1) tree[k].w1 += v;
31             if(com == 2) tree[k].w1 *= v;
32             if(com == 3) tree[k].w1 = v;
33             tree[k].w1 %= MOD;
34             tree[k].w2 = (tree[k].w1 * tree[k].w1)%MOD;
35             tree[k].w3 = (tree[k].w2 * tree[k].w1)%MOD;
36         }
37         else {
38             int m = mid;
39             if(x <= m) change_interval(L, x, y, v, com);
40             if(y > m) change_interval(R, x, y, v, com);
41             tree[k].w1 = tree[L].w1 + tree[R].w1;
42             tree[k].w2 = tree[L].w2 + tree[R].w2;
43             tree[k].w3 = tree[L].w3 + tree[R].w3;
44             tree[k].w1 %= MOD; tree[k].w2 %= MOD; tree[k].w3 %= MOD;
45         }
46     }
47     else {
48         int m = mid;
49         if(x <= m) change_interval(L, x, y, v, com);
50         if(y > m) change_interval(R, x, y, v, com);
51         tree[k].w1 = tree[L].w1 + tree[R].w1;
52         tree[k].w2 = tree[L].w2 + tree[R].w2;
53         tree[k].w3 = tree[L].w3 + tree[R].w3;
54         tree[k].w1 %= MOD; tree[k].w2 %= MOD; tree[k].w3 %= MOD;
55     }
56 }
57 
58 inline int query_interval(int k, int x, int y, int com) {
59     if(tree[k].l >= x && tree[k].r <= y) {
60         if(com == 1) return tree[k].w1;
61         if(com == 2) return tree[k].w2;
62         return tree[k].w3;
63     }
64     int ans = 0;
65     int m = mid;
66     if(x <= m) ans = query_interval(L, x, y, com)%MOD;
67     if(y > m) ans = (ans + query_interval(R, x, y, com)%MOD)%MOD;
68     return ans;
69 }
70 
71 int main() {
72     int n, m;
73     int com, x, y;
74     ll v;
75     while(scanf("%d%d", &n, &m) == 2 && n) {
76         build(1, 1, n);
77         for(int i = 0; i != m; ++i) {
78             scanf("%d%d%d%d", &com, &x, &y, &v);
79             if(com != 4) change_interval(1, x, y, v%MOD, com);
80             else printf("%d
", query_interval(1, x, y, com));
81         }
82     }
83     return 0;
84 }
TLE

// hdu 1754 板子(+如何关闭同步流,以前没用过 但是还是慢了一点 不知道是不是自己操作问题

 1 #include<iostream>// scanf()读入 780ms cin关闭同步流 2964ms 
 2 #include<cstdio>// 多组输入 + 数据量很大(叶子结点数 n <= 200000 询问数 m < 5000)因此cin 比 scanf慢一截
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int MAXN = 200000;
 8 
 9 struct Segmemt_tree {
10     int l, r, mx;
11 } tree[4*MAXN+1];
12 
13 inline void build(int k, int l, int r) {
14     tree[k].l = l; tree[k].r = r;
15     if(tree[k].l == tree[k].r) {
16         scanf("%d", &tree[k].mx); // cin >> tree[k].mx;
17         return ;
18     }
19     int m = (l + r) / 2;
20     build(k*2, l, m);
21     build(k*2+1, m+1, r);
22     tree[k].mx = max(tree[k*2].mx, tree[k*2+1].mx);
23 }
24 
25 inline void change_point(int k, int x, int v) {
26     if(tree[k].l == tree[k].r) {
27         tree[k].mx = v;
28         return ;
29     }
30     int m = (tree[k].l + tree[k].r) / 2;
31     if(x <= m) change_point(k*2, x, v);
32     else change_point(k*2+1, x, v);
33     tree[k].mx = max(tree[k*2].mx, tree[k*2+1].mx);
34 }
35 
36 inline int query_interval(int k, int x, int y) {
37     if(tree[k].l >= x && tree[k].r <= y) {
38         return tree[k].mx;
39     }
40     int m = (tree[k].l + tree[k].r) / 2;
41     int ans = 0;
42     if(x <= m) ans = max(ans, query_interval(k*2, x, y));
43     if(y > m) ans = max(ans, query_interval(k*2+1, x, y));
44     return ans;
45 }
46 
47 int main() {
48     // ios::sync_with_stdio(false);
49     // cin.tie(0);
50     int n, m;
51     int x, y;
52     char com[10];   // string com;
53     while(scanf("%d%d", &n, &m) == 2) {// cin >> n >> m
54         build(1, 1, n);
55         for(int i = 0; i != m; ++i) {
56             scanf("%s%d%d", com, &x, &y); // cin >> com >> x >> y;
57             if(com[0] == 'U') change_point(1, x, y);
58             else printf("%d
", query_interval(1, x, y)); // cout << query_interval(1, x, y) << endl;
59         }
60     }
61     return 0;
62 }
View Code

// poj 3468 简单板子

 1 #include<cstdio>
 2 
 3 const int MAXN = 100000;
 4 typedef long long ll;
 5 
 6 ll ans;
 7 struct Segmemt_tree {
 8     int l, r;
 9     ll f, w;
10 } tree[MAXN*4+1];
11 
12 inline void build(int k, int ll, int rr) {
13     tree[k].l = ll; tree[k].r = rr;
14     if(tree[k].l == tree[k].r) {
15         scanf("%lld", &tree[k].w);
16         return ;
17     }
18     int m = (ll + rr) / 2;
19     build(k*2, ll, m);
20     build(k*2+1, m+1, rr);
21     tree[k].w = tree[k*2].w + tree[k*2+1].w;
22 }
23 
24 inline void down(int k) {
25     tree[k*2].f += tree[k].f;
26     tree[k*2+1].f += tree[k].f;
27     tree[k*2].w += tree[k].f * (tree[k*2].r - tree[k*2].l + 1);
28     tree[k*2+1].w += tree[k].f * (tree[k*2+1].r - tree[k*2+1].l + 1);
29     tree[k].f = 0;
30 }
31 
32 inline void query_interval(int k, int x, int y) {
33     if(tree[k].l >= x && tree[k].r <= y) {
34         ans += tree[k].w;
35         return ;
36     }
37     if(tree[k].f) down(k);
38     int m = (tree[k].l + tree[k].r) / 2;
39     if(x <= m) query_interval(k*2, x, y);
40     if(y > m) query_interval(k*2+1, x, y);
41 }
42 
43 inline void change_interval(int k, int x, int y, ll v) {
44     if(tree[k].l >= x && tree[k].r <= y) {
45         tree[k].w += (tree[k].r - tree[k].l + 1) * v;
46         tree[k].f += v;
47         return ;
48     }
49     if(tree[k].f) down(k);
50     int m = (tree[k].l + tree[k].r) / 2;
51     if(x <= m) change_interval(k*2, x, y, v);
52     if(y > m) change_interval(k*2+1, x, y, v);
53     tree[k].w = tree[k*2].w + tree[k*2+1].w;
54 }
55 
56 int main() {
57     int n, m;
58     scanf("%d%d", &n, &m);
59     build(1, 1, n);
60     int x, y;
61     ll v;
62     char ch;
63     for(int i = 0; i != m; ++i) {
64         getchar();
65         scanf("%c", &ch);
66         ans = 0;
67         if(ch == 'Q') {
68             scanf("%d%d", &x, &y);
69             query_interval(1, x, y);
70             printf("%lld
", ans);
71         }
72         else {
73             scanf("%d%d%lld", &x, &y, &v);
74             change_interval(1, x, y, v);
75         }
76     }
77     return 0;
78 }
View Code

 // poj 3264 简单板子(静态数据)区间最值 含ST(RMQ)解法

  1 #include<cstdio>// poj3264 (静态数据)区间最值(最大或最小) 线段树
  2 #include<algorithm>// memory 2664k | time 2157ms
  3 using namespace std;
  4 
  5 const int MAXN = 50000+5;
  6 
  7 struct segmemt_tree {
  8     int l, r, w, maxn, minn;
  9 } tree[4*MAXN+1];
 10 
 11 inline void build(int k, int l, int r) {
 12     tree[k].l = l; tree[k].r = r;
 13     if(tree[k].l == tree[k].r) {
 14         scanf("%d", &tree[k].w);
 15         tree[k].maxn = tree[k].w;
 16         tree[k].minn = tree[k].w;
 17         return ;
 18     }
 19     int m = (l + r) / 2;
 20     build(k*2, l, m);
 21     build(k*2+1, m+1, r);
 22     tree[k].maxn = max(tree[k*2].maxn, tree[k*2+1].maxn);
 23     tree[k].minn = min(tree[k*2].minn, tree[k*2+1].minn);
 24 }
 25 
 26 inline int get_max(int k, int x, int y) {
 27     if(tree[k].l >= x && tree[k].r <= y) {
 28         return tree[k].maxn;
 29     }
 30     int ans = 0;
 31     int m = (tree[k].l + tree[k].r) / 2;
 32     if(x <= m) ans = max(ans, get_max(k*2, x, y));
 33     if(y > m) ans = max(ans, get_max(k*2+1, x, y));
 34     return ans;
 35 }
 36 
 37 inline int get_min(int k, int x, int y) {
 38     if(tree[k].l >= x && tree[k].r <= y) {
 39         return tree[k].minn;
 40     }
 41     int ans = 1000002;
 42     int m = (tree[k].l + tree[k].r) / 2;
 43     if(x <= m) ans = min(ans, get_min(k*2, x, y));
 44     if(y > m) ans = min(ans, get_min(k*2+1, x, y));
 45     return ans;
 46 }
 47 
 48 int main() {
 49     int n, m;
 50     scanf("%d%d", &n, &m);
 51     build(1, 1, n);
 52     int x, y;
 53     for(int i = 0; i != m; ++i) {
 54         scanf("%d%d", &x, &y);
 55         printf("%d
", get_max(1, x, y)-get_min(1, x, y));
 56     }
 57     return 0;
 58 }
 59 // #include<cstdio>// poj3264 ST(RMQ)解法
 60 // #include<cmath>// memory 13376k time3704ms
 61 // #include<iostream>
 62 // #include<algorithm>
 63 // using namespace std;
 64 
 65 // const int MAXN = 5e4+5;
 66 
 67 // int n, m; // n个数 m次查询
 68 // int a[MAXN];
 69 // int maxn[MAXN][32];// f[i][j] 表示从第i位起的 2^j 个数中的最大值 区间[i, i+(1<<j)-1]
 70 // int minn[MAXN][32];
 71 
 72 // void ST() {
 73 //     for(int i = 1; i <= n; ++i) maxn[i][0] = minn[i][0] = a[i];
 74 //     int m = (int)log2(n*1.0)/log2(2*1.0);
 75 //     for(int j = 1; j <= m; ++j) {
 76 //         for(int i = 1; i+(1<<j)-1 <= n; ++i) {
 77 //             maxn[i][j] = max(maxn[i][j-1], maxn[i+(1<<(j-1))][j-1]);
 78 //             minn[i][j] = min(minn[i][j-1], minn[i+(1<<(j-1))][j-1]);
 79 //         }
 80 //     }
 81 // }
 82 
 83 // int query(int l, int r) {
 84 //     int k = log2(r-l+1)/log2(2.0);
 85 //     return max(maxn[l][k], maxn[r-(1<<k)+1][k]) - min(minn[l][k], minn[r-(1<<k)+1][k]);
 86 // }
 87 
 88 // int main() {
 89 //     scanf("%d%d", &n, &m);
 90 //     for(int i = 1; i <= n; ++i) {
 91 //         scanf("%d", &a[i]);
 92 //     }
 93 //     ST();
 94 //     int l, r;
 95 //     for(int i = 0; i != m; ++i) {
 96 //         scanf("%d%d", &l, &r);
 97 //         printf("%d
", query(l, r));
 98 //     }
 99 //     return 0;
100 // }
View Code

 // poj 1166 板子

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define max 50002
 5 int ans;
 6 struct Segmemt_Tree{
 7     int left, right;
 8     int w;
 9 }tree[4*max+1];
10 
11 inline void build(int k, int l, int r){
12     tree[k].left = l;
13     tree[k].right = r;
14     if(l == r){
15         scanf("%d", &tree[k].w);
16         return ;
17     }
18     int mid = (l+r)/2;
19     build(k*2, l, mid);
20     build(k*2+1, mid+1, r);
21     tree[k].w = tree[k*2].w + tree[k*2+1].w;
22 }
23 
24 inline void add(int k, int index, int x){
25     if(tree[k].left == tree[k].right){
26         tree[k].w += x;
27         return ;
28     }
29     int mid = (tree[k].left+tree[k].right)/2;
30     if(index <= mid){
31         add(k*2, index, x);
32     }
33     else{
34         add(k*2+1, index, x);
35     }
36     tree[k].w = tree[k*2].w + tree[k*2+1].w;
37 }
38 
39 void sum(int k, int x, int y){
40     if(tree[k].left >= x && tree[k].right <= y){
41         ans += tree[k].w;
42         return ;
43     }
44     int mid = (tree[k].left + tree[k].right)/2;
45     if(x <= mid){
46         sum(k*2, x, y);
47     }
48     if(y > mid){
49         sum(k*2+1, x, y);
50     }
51 }
52 
53 int main()
54 {
55     int num;
56     int kk = 1;
57     cin >> num;
58     while(num--){
59         cout << "Case " << kk << ":" << endl;
60         ++kk;
61         int n;
62         cin >> n;
63         build(1, 1, n);
64         
65         char str[10];
66         int a, b;
67         while(~scanf("%s", str)){
68             if(str[0] != 'Q' && str[0] != 'E'){
69                 scanf("%d%d", &a, &b);
70                 if(str[0] == 'A'){
71                     add(1, a, b);
72                 }
73                 if(str[0] == 'S'){
74                     add(1, a, -b);
75                 }
76             }
77             else if(str[0] == 'Q'){
78                 scanf("%d%d", &a, &b);
79                 ans = 0;
80                 sum(1, a, b);
81                 cout << ans << endl;
82             }
83             else{
84                 break;
85             }
86         }
87     }
88     return 0;
89 }
View Code

 // hdu 1698 板子

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 const int MAXN = 100005;
 6 
 7 struct segmemt_tree {
 8     int l, r, w, f;
 9 } tree[4*MAXN+1];
10 
11 inline void build(int k, int l, int r) {
12     tree[k].l = l; tree[k].r = r;
13     if(tree[k].l == tree[k].r) {
14         tree[k].w = 1; tree[k].f = 0;
15         return ;
16     }
17     int m = (l + r) / 2;
18     build(k*2, l, m);
19     build(k*2+1, m+1, r);
20     tree[k].w = tree[k*2].w + tree[k*2+1].w;
21     tree[k].f = 0;
22 }
23 
24 inline void down(int k) {
25     tree[k*2].f = tree[k].f;
26     tree[k*2+1].f = tree[k].f;
27     tree[k*2].w = tree[k].f * (tree[k*2].r - tree[k*2].l + 1);
28     tree[k*2+1].w = tree[k].f * (tree[k*2+1].r - tree[k*2+1].l + 1);
29     tree[k].f = 0;
30 }
31 
32 inline void change_interval(int k, int x, int y, int v) {
33     if(tree[k].l >= x && tree[k].r <= y) {
34         tree[k].f = v;
35         tree[k].w = v * (tree[k].r - tree[k].l + 1);
36         return ;
37     }
38     if(tree[k].f) down(k);
39     int m = (tree[k].l + tree[k].r) / 2;
40     if(x <= m) change_interval(k*2, x, y, v);
41     if(y > m) change_interval(k*2+1, x, y, v);
42     tree[k].w = tree[k*2].w + tree[k*2+1].w;
43 }
44 
45 int main() {
46     // ios::sync_with_stdio(false);
47     // cin.tie(0);
48     int T, cnt = 1;
49     scanf("%d", &T); // cin >> T;
50     while(T--) {
51         int n, m;
52         int x, y, v;
53         scanf("%d%d", &n, &m); // cin >> n >> m;
54         build(1, 1, n);
55         for(int i = 0; i != m; ++i) {
56             scanf("%d%d%d", &x, &y, &v); // cin >> x >> y >> v;
57             change_interval(1, x, y, v);
58         }
59         printf("Case %d: The total value of the hook is %d.
", cnt++, tree[1].w);
60         // cout << "Case " << cnt++ << ": The total value of the hook is " << tree[1].w << ".
";
61     }
62     return 0;
63 }
View Code

 // hdu 4027 板子

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int MAXN = 100000;
 7 typedef long long ll;
 8 
 9 struct segmemt_tree {
10     int l, r;
11     ll w;
12 } tree[4*MAXN+1];
13 
14 inline void build(int k, int l, int r) {
15     tree[k].l = l; tree[k].r = r;
16     if(tree[k].l == tree[k].r) {
17         scanf("%lld", &tree[k].w);
18         return ;
19     }
20     int m = (l + r) / 2;
21     build(k*2, l, m);
22     build(k*2+1, m+1, r);
23     tree[k].w = tree[k*2].w + tree[k*2+1].w;
24 }
25 
26 inline ll down(int k) {
27     if(tree[k].r - tree[k].l + 1 == tree[k].w) return tree[k].w;
28     if(tree[k].l == tree[k].r) return tree[k].w = (ll)sqrt((double)tree[k].w);
29     return tree[k].w = down(k*2) + down(k*2+1);
30 }
31 
32 inline void change_interval(int k, int x, int y) {
33     if(tree[k].r - tree[k].l + 1 == tree[k].w) return ;
34     if(tree[k].l >= x && tree[k].r <= y) {    
35         tree[k].w = down(k);
36         return ;
37     }
38     int m = (tree[k].l + tree[k].r) / 2;
39     if(x <= m) change_interval(k*2, x, y);
40     if(y > m) change_interval(k*2+1, x, y);
41     tree[k].w = tree[k*2].w + tree[k*2+1].w;
42 }
43 
44 inline ll query_interval(int k, int x, int y) {
45     if(tree[k].l >= x && tree[k].r <= y) return tree[k].w;
46     int m = (tree[k].l + tree[k].r) / 2;
47     ll ans = 0;
48     if(x <= m) ans += query_interval(k*2, x, y);
49     if(y > m) ans += query_interval(k*2+1, x, y);
50     return ans;
51 }
52 
53 int main() {
54     int n, m, cnt = 1;
55     int com, x, y;
56     while(scanf("%d", &n) == 1) {
57         build(1, 1, n);
58         printf("Case #%d:
", cnt++);
59         scanf("%d", &m);
60         for(int i = 0; i != m; ++i) {
61             scanf("%d%d%d", &com, &x, &y);
62             if(x > y) swap(x, y);
63             if(com == 0) change_interval(1, x, y);
64             else printf("%lld
", query_interval(1, x, y));
65         }
66         printf("
");
67     }
68     return 0;
69 }
View Code
原文地址:https://www.cnblogs.com/pupil-xj/p/11623782.html