线段树总结
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 }
区间修改:
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 }
一、点修改:
二、区间修改:
POJ3468 A Simple Problem with Integers
HDU4027 Can you answer these queries?
三、区间染色:
四、区间合并:
五、连续型线段树(求面积、周长、体积):
以上是关于线段树总结的主要内容,如果未能解决你的问题,请参考以下文章