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;