线段树学习

标记下模板,需要的时候抄写

1.线段树 单点更新,区间查询

https://hihocoder.com/contest/offers27/problem/3

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 typedef long long ll;
 4 using namespace std;
 5 typedef pair<int, int> pii;
 6 const int maxn = 2e5 + 10;
 7 int f[maxn * 4];
 8 int a[maxn];
 9 vector<int> e[100010];
10 int n;
11 int ti[maxn];
12 int cnt = 0;
13 int rt[100010][2];
14 void dfs(int u, int p) {
15     ti[++cnt] = u;
16     rt[u][0] = cnt;
17     for (int  x : e[u]) {
18         if(x == p) continue;
19         dfs(x, u);
20     }
21     ti[++cnt] = u;
22     rt[u][1] = cnt;
23 }
24 void bt(int x, int y, int o) {
25     if(x == y) {
26         f[o] = a[ti[x]];
27         return;
28     }
29     int mid = (x + y) >> 1;
30     bt(x, mid, o * 2);
31     bt(mid + 1, y, o * 2 + 1);
32     f[o] = min(f[o * 2], f[o * 2 + 1]);
33 }
34 int tx1, ty1;
35 int ask(int x, int y, int o) {
36     if(x >= tx1 && y <= ty1) return f[o];
37     int mid = (x + y) >> 1;
38     int res = INT_MAX;
39     if(tx1 <= mid)
40         res = min(res, ask(x, mid, o * 2));
41     if(ty1 >= mid + 1)
42         res = min(res, ask(mid + 1, y, o * 2 + 1));
43     return res;
44 }
45 void up(int x, int y, int o) {
46     if(y < tx1 || x > tx1) return;
47     if(x == y && x == tx1) {
48         f[o] = ty1;
49         //cout << o << " asd " << f[o] << " " << y1 << endl;
50         return;
51     }
52     int mid = (x + y) >> 1;
53     if(tx1 <= mid) up(x, mid, o * 2);
54     else up(mid + 1, y, o * 2 + 1);
55     f[o] = min(f[o * 2], f[o * 2 + 1]);
56     //cout << o << " asd " << f[o] << endl;
57 }
58 void solve() {
59     scanf("%d", &n);
60     for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
61     int x, y;
62     for (int i = 2; i <= n; i++) {
63         scanf("%d", &x);
64         e[x].pb(i);
65     }
66     dfs(1, 0);
67     bt(1, cnt, 1);
68     int m;
69     scanf("%d", &m);
70     while(m--) {
71         scanf("%d%d", &x, &y);
72         //cout << x << " " << y << endl;
73         if(x == 1) {
74             scanf("%d", &x);
75             swap(x, y);
76             tx1 = rt[x][0];
77             ty1 = y;
78             up(1, cnt, 1);
79             tx1 = rt[x][1];
80             up(1, cnt, 1);
81 
82         } else {
83             tx1 = rt[y][0]; ty1 = rt[y][1];
84             int t = ask(1, cnt, 1);
85             printf("%d
", t);
86         }
87     }
88 
89 }
90 
91 int main() {
92     //freopen("test.in", "r", stdin);
93     //freopen("test.out", "w", stdout);
94     solve();
95     return 0;
96 }
View Code

2. 区间更新,区间查询, lazy标记

https://hihocoder.com/contest/offers28/problem/3

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 typedef long long ll;
 4 using namespace std;
 5 typedef pair<int, int> pii;
 6 const int maxn = 1e5 + 10;
 7 
 8 int n, m, q;
 9 pii a[maxn], b[maxn];
10 
11 //tree
12 int x, y, v;
13 int sum[1863000],tag[1863000];
14 #define pd(o,l,r) tag[o<<1] += tag[o], tag[o<<1|1]+=tag[o],sum[o<<1]+=tag[o],sum[o<<1|1]+=tag[o],tag[o]=0
15 #define mid (l+r>>1)
16 void update(int o,int l,int r){
17     //cout << o << " " << l << " " << r << endl;
18     x<=l&&r<=y?
19     tag[o]+=v,sum[o]=sum[o] + v:
20         (tag[o]?pd(o,l,r),1:1,x<=mid?update(o<<1,l,mid),1:1,mid<y?update(o<<1|1,mid+1,r),1:1,sum[o]= max(sum[o<<1], sum[o<<1|1]));
21 }int query(int o,int l,int r){
22     int t = 0;
23     x<=l&&r<=y?t =  sum[o]:(tag[o]?pd(o,l,r),1:1,
24     x<=mid?t = max(t, query(o<<1,l,mid)),1:1,mid<y?t = max(t, query(o<<1|1,mid+1,r)),1:1);
25     return t;
26 }
27 void solve() {
28     scanf("%d%d", &n, &m);
29     int tx, ty;
30     set<int> se;
31     map<int, int> ma;
32     for (int i = 0; i < n; i++) {
33         scanf("%d%d", &tx, &ty);
34         a[i] = {tx, ty}; se.insert(tx); se.insert(ty);
35     }
36     scanf("%d", &q);
37     for (int i = 0; i < q; i++) {
38         scanf("%d%d", &tx, &ty);
39         b[i] = {tx, ty}; se.insert(tx); se.insert(ty);
40     }
41     int cnt = 0;
42     for (int t : se) {
43         ma[t] = ++cnt;
44     }
45     for (int i = 0; i < n; i++) {
46         x = ma[a[i].first], y = ma[a[i].second]-1;
47         //cout << x << " " << y << endl;
48         v = 1;
49 
50         update(1, 1, cnt);//cout << "asd" << endl;
51     }
52     for (int i = 0; i < q; i++) {
53         x = ma[b[i].first], y = ma[b[i].second]-1;
54         //cout << x << " " << y << endl;
55         int t = query(1, 1, cnt) + 1;
56         if(t > m) puts("NO");
57         else puts("YES");
58     }
59 }
60 
61 int main() {
62     //freopen("test.in", "r", stdin);
63     //freopen("test.out", "w", stdout);
64     solve();
65     return 0;
66 }
View Code

https://hihocoder.com/contest/hiho20/problem/1

 1 #include<cstdio>
 2 #define mid (l+r>>1)
 3 #define pd(o,l,r) tag[o<<1]=tag[o<<1|1]=tag[o],sum[o<<1]=tag[o]*(mid-l+1),sum[o<<1|1]=tag[o]*(r-mid),tag[o]=0
 4 int ans,sum[263000],tag[263000],v,n,q,op,x,y,i,aa;char ch;int F(){
 5     while(ch=getchar(),ch<'0'||ch>'9');aa=ch-48;
 6     while(ch=getchar(),ch>='0'&&ch<='9')aa=aa*10+ch-48;return aa;
 7 }void bt(int o,int l,int r){
 8     l==r?sum[o]=F():(bt(o<<1,l,mid),bt(o<<1|1,mid+1,r),sum[o]=sum[o<<1]+sum[o<<1|1]);
 9 }void update(int o,int l,int r){
10     x<=l&&r<=y?tag[o]=v,sum[o]=v*(r-l+1):(tag[o]?pd(o,l,r),1:1,
11     x<=mid?update(o<<1,l,mid),1:1,mid<y?update(o<<1|1,mid+1,r),1:1,sum[o]=sum[o<<1]+sum[o<<1|1]);
12 }void query(int o,int l,int r){
13     x<=l&&r<=y?ans+=sum[o]:(tag[o]?pd(o,l,r),1:1,
14     x<=mid?query(o<<1,l,mid),1:1,mid<y?query(o<<1|1,mid+1,r),1:1);
15 }int main(){
16     for(bt(1,1,n=F()),q=F();q--;op=F(),x=F(),y=F(),
17     op?v=F(),update(1,1,n),1:(ans=0,query(1,1,n),printf("%d
",ans)));
18 }
View Code

上面这个代码是十佳代码代码里面的,我一般都是学的这个模板。

原文地址:https://www.cnblogs.com/y119777/p/7599228.html