題目鏈接:No Link, Cut Tree!
因爲是完全二叉樹,所以我們可以發現只有logn層,所以我們可以對每一層暴力統計。
怎麼統計呢?
我們可以利用dfs序,對每一層存下dfs序,然後對於不要的dfs序區間,二分即可找到對應位置。
然後怎麼快速求值呢?顯然可以前綴和。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,m,w[N],st[N],ed[N],dfn[N],cnt,mx;
vector<int> g[N],v[N],sum[N];
void dfs(int x,int fa,int dep){
st[x]=++cnt; dfn[cnt]=x; v[dep].push_back(st[x]); mx=max(mx,dep);
for(int to:g[x]) dfs(to,x,dep+1);
ed[x]=cnt;
}
inline int calc(int x){
int res=0,tmp=0;
for(int i=1;i<=mx;i++){
tmp=0;
int l=lower_bound(v[i].begin(),v[i].end(),st[x])-v[i].begin();
int r=upper_bound(v[i].begin(),v[i].end(),ed[x])-v[i].begin();
if(l) tmp+=sum[i][l-1];
if(r!=v[i].size()){
tmp+=sum[i].back();
if(r) tmp-=sum[i][r-1];
}
res=max(res,tmp);
}
return res;
}
signed main(){
cin>>n>>m>>w[1];
for(int i=1,a,b,c;i<n;i++) scanf("%d %d %d",&a,&b,&c),g[b].push_back(a),w[a]=c;
dfs(1,0,1);
for(int i=1;i<=mx;i++){
sum[i].resize(v[i].size());
sum[i][0]=w[dfn[v[i][0]]];
for(int j=1;j<v[i].size();j++) sum[i][j]=sum[i][j-1]+w[dfn[v[i][j]]];
}
for(int i=1,x;i<=m;i++) scanf("%d",&x),printf("%d\n",calc(x));
return 0;
}