线段树总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树总结相关的知识,希望对你有一定的参考价值。

 

模板:

点修改:

技术分享
 1 int sum[maxn<<2], maxv[maxn<<2], minv[maxn<<2];  
 2   
 3 void maintain(int u)  
 4 {  
 5     int lc = u*2, rc = u*2+1;  
 6     sum[u] = sum[lc] + sum[rc];  
 7     maxv[u] = max(maxv[lc], maxv[rc]);  
 8     minv[u] = min(minv[lc]. minv[rc]);  
 9 }  
10   
11 void build(int u, int l, int r)  
12 {  
13     if(l==r)  
14     {  
15         sum[u] = maxv[u] = minv[u] = 0;  
16         return;  
17     }  
18       
19     int mid = (l+r)>>1;  
20     build(u*2, l, mid);  
21     build(u*2+1, mid+1, r);  
22     maintain(u);  
23 }  
24   
25 void add_val(int u,int l,int r,int x, int val)  
26 {  
27     if(l==r)  
28     {  
29         sum[u] += val;  
30         maxv[u] += val;  
31         minv[u] += val;  
32         return ;  
33     }  
34       
35     int mid = (l+r)>>1;  
36     if(x<=mid) add_val(u*2, l, mid, x, val);  
37     else add_val(u*2+1, mid+1, r, x, val);  
38     maintain(u);  
39 }  
40   
41 void set_val(int u, int l, int r, int x, int val)  
42 {  
43     if(l==r)  
44     {  
45         sum[u] = val;  
46         maxv[u] = val;  
47         minv[u] = val;  
48         return;  
49     }  
50       
51     int mid = (l+r)>>1;  
52     if(x<=mid) set_val(u*2, l, mid, x, val);  
53     else set_val(u*2+1, mid+1, r, x, val);  
54     maintain(u);  
55 }  
56   
57 int maxx, minn;   
58 int query(int u,int l, int r, int x, int y)  
59 {  
60     if(x<=l && r<=y)  
61     {  
62         maxx = max(maxx, maxv[u]);  
63         minn = min(minn, minv[u]);  
64         return sum[u];  
65     }  
66       
67     int ret = 0;  
68     int mid = (l+r)>>1;  
69     if(x<=mid) ret += query(u*2, l, mid, x, y);  
70     if(y>=mid+1) ret += query(u*2+1, mid+1, r, x ,y);  
71     return ret;  
72 }  
View Code

 

区间修改:

技术分享
  1 int sum[maxn<<2], maxv[maxn<<2], minv[maxn<<2], addv[maxn<<2], setv[maxn<<2];  
  2   
  3 void pushup(int u)  
  4 {  
  5     int l = 2*u, r = 2*u+1;  
  6     sum[u] = sum[l] + sum[r];  
  7     maxv[u] = max(maxv[l], maxv[r]);  
  8     minv[u] = min(minv[l], minv[r]);  
  9 }  
 10   
 11 void pushdown(int u, int len)  
 12 {  
 13     int lc = 2*u, rc = 2*u+1;  
 14     if(setv[u]>=0)  
 15     {  
 16         addv[lc] = addv[rc] = 0;  
 17         minv[lc] = minv[rc] = maxv[lc] = maxv[rc] = setv[u];  
 18         sum[lc] = (len+1)/2*setv[u];  
 19         sum[rc] = len/2*setv[u];  
 20         setv[lc] = setv[rc] = setv[u];  
 21         setv[u] = -1;  
 22     }  
 23   
 24     if(addv[u])  
 25     {  
 26         sum[lc] += (len+1)/2*addv[u];  
 27         sum[rc] += len/2*addv[u];  
 28         maxv[lc] += addv[u]; minv[lc] += addv[u];  
 29         maxv[rc] += addv[u]; minv[rc] += addv[u];  
 30         addv[lc] += addv[u]; addv[rc] += addv[u];  
 31         addv[u] = 0;  
 32     }  
 33 }  
 34   
 35 void build(int u, int l, int r)  
 36 {  
 37     if(l==r)  
 38     {  
 39         sum[u] = maxv[u] = minv[u] = 0;  
 40         return;  
 41     }  
 42   
 43     int mid = (l+r)>>1;  
 44     build(u*2, l, mid);  
 45     build(u*2+1, mid+1, r);  
 46     pushup(u);  
 47 }  
 48   
 49 void set_val(int u, int l, int r, int x, int y, int val)  
 50 {  
 51     if(x<=l && r<=y)  
 52     {  
 53         addv[u] = 0;  
 54         maxv[u] = minv[u] = val;  
 55         sum[u] = (r-l+1)*val;  
 56         setv[u] = val;  
 57         return;  
 58     }  
 59   
 60     pushdown(u, r-l+1);  
 61     int mid = (l+r)>>1;  
 62     if(x<=mid) set_val(u*2, l, mid, x, y, val);  
 63     if(y>=mid+1) set_val(u*2+1, mid+1, r, x, y, val);  
 64     pushup(u);  
 65 }  
 66   
 67   
 68 void add_val(int u, int l, int r, int x, int y, int val)  
 69 {  
 70     if(x<=l && r<=y)  
 71     {  
 72         maxv[u] += val;  
 73         minv[u] += val;  
 74         sum[u] += (r-l+1)*val;  
 75         addv[u] += val;  
 76         return;  
 77     }  
 78   
 79     pushdown(u, r-l+1);  
 80     int mid = (l+r)>>1;  
 81     if(x<=mid)  add_val(u*2, l, mid, x, y, val);  
 82     if(y>=mid+1) add_val(u*2+1, mid+1, r, x, y, val);  
 83     pushup(u);  
 84 }  
 85   
 86 int ansmax, ansmin;  
 87 int query(int u, int l, int r, int x, int y)  
 88 {  
 89     if(x<=l && r<=y)  
 90     {  
 91         ansmax = max(ansmax, maxv[u]);  
 92         ansmin = min(ansmin, minv[u]);  
 93         return sum[u];  
 94     }  
 95   
 96     pushdown(u, r-l+1);  
 97     int mid = (l+r)>>1;  
 98     int ret = 0;  
 99     if(x<=mid) ret += query(u*2, l, mid, x, y);  
100     if(y>=mid+1) ret += query(u*2+1, mid+1, r, x, y);  
101     return ret;  
102 }  
View Code

 

 

一、点修改:

HDU1166 敌兵布阵

HDU1754 —— I Hate It

POJ3264 Balanced Lineup 

 

二、区间修改:

POJ3468 A Simple Problem with Integers

HDU4027 Can you answer these queries?

HDU3974 Assign the task 

 

三、区间染色:

HDU1698 Just a Hook

ZOJ1610 Count the Colors 

POJ2528 Mayor‘s posters

 

四、区间合并:

HDU1540 Tunnel Warfare 

 

五、连续型线段树(求面积、周长、体积):

HDU1542 Atlantis

HDU1255 覆盖的面积

POJ1177 Picture

HDU3642 Get The Treasury

 

以上是关于线段树总结的主要内容,如果未能解决你的问题,请参考以下文章

P1243~P1247 线段树模板题总结

线段树分治总结

线段树入门总结

线段树分治总结(线段树分治,线段树,并查集,树的dfn序,二分图染色)

线段树总结

权值线段与主席树总结