小A走到一个山脚下,准备给自己造一个小屋。这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到
山顶放了格水。于是小A面前出现了一个瀑布。作为平民的小A只好老实巴交地爬山堵水。那么问题来了:我们把这
个瀑布看成是一个n个节点的树,每个节点有权值(爬上去的代价)。小A要选择一些节点,以其权值和作为代价将
这些点删除(堵上),使得根节点与所有叶子结点不连通。问最小代价。不过到这还没结束。小A的朋友觉得这样
子太便宜小A了,于是他还会不断地修改地形,使得某个节点的权值发生变化。不过到这还没结束。小A觉得朋友做
得太绝了,于是放弃了分离所有叶子节点的方案。取而代之的是,每次他只要在某个子树中(和子树之外的点完全
无关)。于是他找到你。
输入文件第一行包含一个数n,表示树的大小。
接下来一行包含n个数,表示第i个点的权值。
接下来n-1行每行包含两个数fr,to。表示书中有一条边(fr,to)。
接下来一行一个整数,表示操作的个数。
接下来m行每行表示一个操作,若该行第一个数为Q,则表示询问操作,后面跟一个参数x,表示对应子树的根;若
为C,则表示修改操作,后面接两个参数x,to,表示将点x的权值加上to。
n<=200000,保证任意to都为非负数
对于每次询问操作,输出对应的答案,答案之间用换行隔开。
1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #define lll spc<<1
5 #define rrr spc<<1|1
6 typedef long long lnt;
7 const int N=200010;
8 struct trnt{
9 lnt minv;
10 lnt lzt;
11 }tr[N<<2];
12 struct pnt{
13 int hd;
14 int fa;
15 int tp;
16 int dp;
17 int wgt;
18 int mxs;
19 int ind;
20 lnt val;
21 lnt f;
22 lnt sigf;
23 }p[N];
24 struct ent{
25 int twd;
26 int lst;
27 }e[N<<1];
28 int cnt;
29 int n,m;
30 int dfn;
31 int plc[N];
32 char cmd[100];
33 void ade(int f,int t)
34 {
35 cnt++;
36 e[cnt].twd=t;
37 e[cnt].lst=p[f].hd;
38 p[f].hd=cnt;
39 return ;
40 }
41 void Basic_dfs(int x,int f)
42 {
43 p[x].fa=f;
44 p[x].dp=p[f].dp+1;
45 p[x].wgt=1;
46 int maxs=-1;
47 for(int i=p[x].hd;i;i=e[i].lst)
48 {
49 int to=e[i].twd;
50 if(to==f)
51 continue;
52 Basic_dfs(to,x);
53 p[x].sigf+=p[to].f;
54 p[x].wgt+=p[to].wgt;
55 if(maxs<p[to].wgt)
56 {
57 maxs=p[to].wgt;
58 p[x].mxs=to;
59 }
60 }
61 if(!p[x].mxs)
62 p[x].sigf=0x3f3f3f3f;
63 p[x].f=std::min(p[x].val,p[x].sigf);
64 return ;
65 }
66 void Build_dfs(int x,int top)
67 {
68 if(!x)
69 return ;
70 p[x].tp=top;
71 p[x].ind=++dfn;
72 plc[dfn]=x;
73 Build_dfs(p[x].mxs,top);
74 for(int i=p[x].hd;i;i=e[i].lst)
75 {
76 int to=e[i].twd;
77 if(p[to].ind)
78 continue;
79 Build_dfs(to,to);
80 }
81 return ;
82 }
83 void pushup(int spc)
84 {
85 tr[spc].minv=std::min(tr[lll].minv,tr[rrr].minv);
86 return ;
87 }
88 void add(int spc,lnt v)
89 {
90 tr[spc].lzt+=v;
91 tr[spc].minv-=v;
92 return ;
93 }
94 void pushdown(int spc)
95 {
96 if(tr[spc].lzt)
97 {
98 add(lll,tr[spc].lzt);
99 add(rrr,tr[spc].lzt);
100 tr[spc].lzt=0;
101 }
102 return ;
103 }
104 void build(int l,int r,int spc)
105 {
106 if(l==r)
107 {
108 tr[spc].minv=p[plc[l]].val-p[plc[l]].sigf;
109 return ;
110 }
111 int mid=(l+r)>>1;
112 build(l,mid,lll);
113 build(mid+1,r,rrr);
114 pushup(spc);
115 return ;
116 }
117 void update(int l,int r,int pos,int spc,lnt v)
118 {
119 if(l==r)
120 {
121 add(spc,-v);
122 return ;
123 }
124 int mid=(l+r)>>1;
125 pushdown(spc);
126 if(pos<=mid)
127 update(l,mid,pos,lll,v);
128 else
129 update(mid+1,r,pos,rrr,v);
130 pushup(spc);
131 return ;
132 }
133 int scupdate(int l,int r,int ll,int rr,int spc,lnt v)
134 {
135 if(l>rr||ll>r)
136 return 0;
137 if(l==r)
138 {
139 add(spc,v);
140 if(tr[spc].minv<=0)
141 return plc[l];
142 return 0;
143 }
144 if(ll<=l&&r<=rr&&tr[spc].minv>v)
145 {
146 add(spc,v);
147 return 0;
148 }
149 int mid=(l+r)>>1;
150 pushdown(spc);
151 int plcc=scupdate(mid+1,r,ll,rr,rrr,v);
152 if(!plcc)
153 plcc=scupdate(l,mid,ll,rr,lll,v);
154 pushup(spc);
155 return plcc;
156 }
157 lnt query(int l,int r,int pos,int spc)
158 {
159 if(l==r)
160 return tr[spc].minv;
161 int mid=(l+r)>>1;
162 pushdown(spc);
163 if(pos<=mid)
164 return query(l,mid,pos,lll);
165 return query(mid+1,r,pos,rrr);
166 }
167 void Update(int x,lnt v)
168 {
169 if(v<=0||!x)
170 return ;
171 while(x)
172 {
173 int tp=scupdate(1,n,p[p[x].tp].ind,p[x].ind,1,v);
174 if(!tp)
175 x=p[p[x].tp].fa;
176 else{
177 Update(p[tp].fa,query(1,n,p[tp].ind,1)+v);
178 return ;
179 }
180 }
181 }
182 int main()
183 {
184 scanf("%d",&n);
185 for(int i=1;i<=n;i++)
186 scanf("%d",&p[i].val);
187 for(int i=1;i<n;i++)
188 {
189 int a,b;
190 scanf("%d%d",&a,&b);
191 ade(a,b);
192 ade(b,a);
193 }
194 Basic_dfs(1,1);
195 Build_dfs(1,1);
196 build(1,n,1);
197 scanf("%d",&m);
198 while(m--)
199 {
200 scanf("%s",cmd+1);
201 if(cmd[1]==‘Q‘)
202 {
203 int x;
204 scanf("%d",&x);
205 printf("%lld\n",std::min(p[x].val,p[x].val-query(1,n,p[x].ind,1)));
206 }else{
207 int x,v;
208 scanf("%d%d",&x,&v);
209 if(!v)
210 continue;
211 p[x].val+=v;
212 update(1,n,p[x].ind,1,v);
213 lnt tmp=p[x].val-query(1,n,p[x].ind,1);
214 p[x].f=std::min(p[x].val,tmp);
215 Update(p[x].fa,p[x].f+v-p[x].val);
216 }
217 }
218 return 0;
219 }