1 const int N=1e5+2; 2 3 struct Segment_tree 4 { 5 struct Node 6 { 7 int val,Max,lazy; 8 int Size,son[2]; 9 void init() 10 { 11 lazy=son[0]=son[1]=Size=val=Max=val=0; 12 } 13 } T[N*4]; 14 int cnt,root; 15 16 void init(int l,int r,int *a) 17 { 18 cnt=0; 19 root=build(l,r,a); 20 } 21 22 void update(int pos) 23 { 24 if(T[pos].Size==1)return ; 25 T[pos].val=T[T[pos].son[0]].val+T[T[pos].son[1]].val; 26 if(T[T[pos].son[0]].lazy) 27 { 28 T[pos].val+=T[T[pos].son[0]].lazy*T[T[pos].son[0]].Size; 29 } 30 if(T[T[pos].son[1]].lazy) 31 { 32 T[pos].val+=T[T[pos].son[1]].lazy*T[T[pos].son[1]].Size; 33 } 34 T[pos].Max=max(T[T[pos].son[1]].Max+T[T[pos].son[1]].lazy,T[T[pos].son[0]].Max+T[T[pos].son[0]].lazy); 35 } 36 37 void pushdown(int pos) 38 { 39 if(pos==0)return ; 40 if(T[pos].lazy) 41 { 42 if(T[pos].son[0]) 43 { 44 int x=T[pos].son[0]; 45 if(T[x].Size==1) 46 { 47 T[x].val+=T[pos].lazy; 48 T[x].Max+=T[pos].lazy; 49 } 50 else 51 { 52 T[x].lazy+=T[pos].lazy; 53 } 54 } 55 if(T[pos].son[1]) 56 { 57 int x=T[pos].son[1]; 58 if(T[x].Size==1) 59 { 60 T[x].val+=T[pos].lazy; 61 T[x].Max+=T[pos].lazy; 62 } 63 else 64 { 65 T[x].lazy+=T[pos].lazy; 66 } 67 } 68 T[pos].lazy=0; 69 } 70 } 71 72 int build(int l,int r,int *a) 73 { 74 int pos=++cnt; 75 T[pos].init(); 76 T[pos].Size=r-l+1; 77 if(l==r) 78 { 79 T[pos].val=a[l]; 80 T[pos].Max=a[l]; 81 return pos; 82 } 83 int mid=(l+r)>>1; 84 T[pos].son[0]=build(l,mid,a); 85 T[pos].son[1]=build(mid+1,r,a); 86 update(pos); 87 return pos; 88 } 89 90 void add(int L,int R,int l,int r,int v,int pos=1) 91 { 92 if(L==l&&R==r) 93 { 94 if(l==r) 95 { 96 T[pos].val+=v; 97 T[pos].Max+=v; 98 } 99 else 100 { 101 T[pos].lazy+=v; 102 } 103 return ; 104 } 105 int mid=(L+R)>>1; 106 if(r<=mid) 107 add(L,mid,l,r,v,T[pos].son[0]); 108 else if(l>mid) 109 add(mid+1,R,l,r,v,T[pos].son[1]); 110 else 111 { 112 add(L,mid,l,mid,v,T[pos].son[0]); 113 add(mid+1,R,mid+1,r,v,T[pos].son[1]); 114 } 115 update(pos); 116 } 117 118 int query_Max(int L,int R,int l,int r,int pos=1) 119 { 120 pushdown(pos); 121 update(pos); 122 if(L==l&&R==r) 123 { 124 return T[pos].Max; 125 } 126 int mid=(L+R)>>1; 127 if(r<=mid) 128 return query_Max(L,mid,l,r,T[pos].son[0]); 129 else if(l>mid) 130 return query_Max(mid+1,R,l,r,T[pos].son[1]); 131 else 132 return max(query_Max(L,mid,l,mid,T[pos].son[0]),query_Max(mid+1,R,mid+1,r,T[pos].son[1])); 133 } 134 135 int query_Sum(int L,int R,int l,int r,int pos=1) 136 { 137 pushdown(pos); 138 update(pos); 139 if(L==l&&R==r) 140 { 141 return T[pos].val; 142 } 143 int mid=(L+R)>>1; 144 if(r<=mid) 145 return query_Sum(L,mid,l,r,T[pos].son[0]); 146 else if(l>mid) 147 return query_Sum(mid+1,R,l,r,T[pos].son[1]); 148 else 149 return query_Sum(L,mid,l,mid,T[pos].son[0])+query_Sum(mid+1,R,mid+1,r,T[pos].son[1]); 150 } 151 152 }tree;