No Link, Cut Tree!

題目鏈接: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章