CF1797D
Accepted。
题解
他提到重儿子,所以不要树链剖分。令
对于操作 1,dfs 一遍预处理一个数组
对于操作 2,发现其只会影响
操作 2 的具体过程其实是:
然后就是对
其中
此时
在
STL 很神奇吧!
此题结。
代码
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
using namespace std;
const int N=1e5+5;
int n,m;
int head[N],to[2*N],nxt[2*N],idx;
int siz[N],fa[N];
ll s[N],a[N];
set<pii> son[N];
inline void add(int x,int y) {
nxt[++idx]=head[x],head[x]=idx,to[idx]=y;
return;
}
void dfs(int x) {
siz[x]=1,s[x]=a[x];
for(int i=head[x];i;i=nxt[i]) {
int y=to[i];
if(y!=fa[x]) {
fa[y]=x;
dfs(y);
siz[x]+=siz[y],s[x]+=s[y];
son[x].insert({-siz[y],y});
}
}
return;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs(1);
while(m--) {
int op,x;
scanf("%d%d",&op,&x);
if(op==1) printf("%lld\n",s[x]);
if(op==2) {
if(son[x].empty()) continue;
int hv=(*son[x].begin()).second;
son[fa[x]].erase(son[fa[x]].find({-siz[x],x}));
s[x]-=s[hv],s[hv]+=s[x];
siz[x]-=siz[hv],siz[hv]+=siz[x];
son[hv].insert({-siz[x],x});
son[fa[x]].insert({-siz[hv],hv});
son[x].erase(son[x].begin());
fa[hv]=fa[x],fa[x]=hv;
}
}
return 0;
}