zkw线段树

Posted mediocrekonjac

tags:

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

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 100000 + 10;
 7 struct Node{
 8   int sum,mx,mn;
 9 }T[maxn<<2];
10 int M,a[maxn];
11 void build(int n)
12 {
13   for( M = 1; M <= n+1; M <<= 1);
14   for( int i = M + 1; i <= M + n; i++ )T[i].sum = T[i].mx = T[i].mn = a[i-M];
15   for( int i = M - 1; i; i-- ){
16     T[i].sum = T[i<<1].sum + T[i<<1|1].sum;
17 
18     T[i].mx = max(T[i<<1].mx,T[i<<1|1].mx);
19     T[i<<1].mx -= T[i].mx;T[i<<1|1].mx -= T[i].mx;
20 
21     T[i].mn = min(T[i<<1].mn,T[i<<1|1].mn);
22     T[i<<1].mn -= T[i].mn;T[i<<1|1].mn -= T[i].mn;
23   }
24 }
25 void update(int x,int v,int A = 0)
26 {
27   int s,t;
28   for( s = x+M-1,t = x+M+1; s^t^1; s>>=1,t>>=1 ){
29     if(~s&1)T[s^1].mx += v,T[s^1].mn += v;
30     if( t&1)T[t^1].mx += v,T[t^1].mn += v;
31     A = max(T[s].mx,T[s^1].mx);T[s].mx -= A;T[s^1].mx -= A;T[s>>1].mx += A;
32     A = max(T[t].mx,T[t^1].mx);T[t].mx -= A;T[t^1].mx -= A;T[t>>1].mx += A;
33 
34     A = min(T[s].mn,T[s^1].mn);T[s].mn -= A;T[s^1].mn -= A;T[s>>1].mn += A;
35     A = min(T[t].mn,T[t^1].mn);T[t].mn -= A;T[t^1].mn -= A;T[t>>1].mn += A;
36   }
37 
38   while(s>1){
39     A = max(T[s].mx,T[s^1].mx),T[s].mx -= A,T[s^1].mx -= A,T[s>>1].mx += A;
40 
41     A = min(T[s].mn,T[s^1].mn),T[s].mn -= A,T[s^1].mn -= A,T[s>>=1].mn += A;
42   }
43 
44   for( T[x+=M].sum += v,x >>= 1; x; x >>= 1){
45     T[x].sum = T[x<<1].sum + T[x<<1|1].sum;
46   }
47 }
48 int querySum(int l,int r,int res = 0)
49 {
50   for( l = l + M - 1,r = r + M + 1; l^r^1; l >>= 1,r >>= 1 ){
51     if(~l&1)res += T[l^1].sum;
52     if( r&1)res += T[r^1].sum;
53   }
54   return res;
55 }
56 int queryMax(int l,int r,int lmx = 0,int rmx = 0)
57 {
58   l += M,r += M;
59   int res ;
60   if(l != r){
61     for( ; l^r^1; l >>= 1,r >>= 1 ){
62       lmx += T[l].mx;rmx += T[r].mx;
63       if(~l&1)lmx = max(lmx,T[l^1].mx);
64       if( r&1)rmx = max(rmx,T[r^1].mx); 
65     }
66   }
67   res = max(lmx+T[l].mx,rmx+T[r].mx);
68   while(l > 1)res += T[l>>=1].mx;
69   return res;
70 }
71 int queryMin(int l,int r,int lmn = 0,int rmn = 0)
72 {
73   l += M,r += M;
74   int res = 0;
75   if(l != r){
76     for( ; l^r^1; l >>= 1,r >>= 1 ){
77       lmn += T[l].mn;rmn += T[r].mn;
78       if(~l&1)lmn = min(lmn,T[l^1].mn);
79       if( r&1)rmn = min(rmn,T[r^1].mn); 
80     }
81   }
82   res = min(lmn+T[l].mn,rmn+T[r].mn);
83   while(l > 1)res += T[l>>=1].mn;
84   return res;
85 }
86 int main()
87 {
88 
89   return 0;
90 }

 

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

浅谈zkw线段树(by Shine_hale)

zkw线段树

HDU 1166 - 敌兵布阵 - [单点修改区间查询zkw线段树]

ZKW线段树

ZKW线段树 非递归版本的线段树

数据结构-ZKW线段树 详解