牛近所LGOJ3057(USACO12 2月)

初回含め排除の問題は、彼は自分自身ではないが、包含と除外のエッセンスました

説明

リンク

あなたを与える\(N- \)超えていないことから、算出した各ノードに対して、右のポイントをポイントして、ツリーを\(K \)すべてのノードの重みと\(P_Iを\)

\(N \ P 10 ^ 5 K \ 20 \)

解決

質問への統計的な答えは、私は少し点線のルールのように感じる(点線のルールを知らなかった行うことはできません)

定義\(F_ {I、J} \) 点からの距離である\(I \)長さ\(J \)右点と

ツリーながら全缶の最初の\(DP \)各ポイントのサブツリー\(ANS \)値の右

その後、我々は、ボトムアップの時から行く方法を見て

直接の親ノードからのプラスマイナスの子ノードツリーに父がなくなっている場合は、重複する答えがあるだろうので一つは、十分ではありません

その後、我々はここで考える含める排除に従事する(ブロガーが複雑なのだと思うようになった、その後、実際には非常に困難ではないことを発見しました)

答えは、親ノードと一緒に、あるとき、第1の距離マイナスマイナス\(2 \)だけで罰金

フォーマル、彼は言いました:

for(int j=k;j>=2;--j) f[t][j]-=f[t][j-2];
for(int j=1;j<=k;++j) f[t][j]+=f[x][j-1];

\(X \)親ノード、\(T \)は子ノードであります

ここでの処理は父親を探しに行われます

コード

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k=='-') f=-1;
		while(isdigit(k)) res=res*10+k-'0',k=getchar();
		return res*f;
	}
	const int N=1e5+10;
	struct node{
		int to,nxt;
	}e[N<<1];
	int head[N],cnt;
	inline void add(int u,int v)
	{
		e[++cnt].nxt=head[u]; e[cnt].to=v;
		return head[u]=cnt,void();
	}
	int fa[N],f[N][30],n,k; 
	inline void dp(int x,int fat)
	{
		fa[x]=fat;
		for(int i=head[x];i;i=e[i].nxt)
		{
			int t=e[i].to; if(t==fat) continue;
			dp(t,x);
			for(int j=1;j<=k;++j) f[x][j]+=f[t][j-1];
		} return ;
	}
	inline void dfs(int x)
	{
		for(int i=head[x];i;i=e[i].nxt)
		{
			int t=e[i].to; if(t==fa[x]) continue;
			for(int j=k;j>=2;--j) f[t][j]-=f[t][j-2];
			for(int j=1;j<=k;++j) f[t][j]+=f[x][j-1];
			dfs(t);
		}return ;
	}
	signed main()
	{
		n=read(); k=read(); 
		for(int i=1,u,v;i<n;++i) u=read(),v=read(),add(u,v),add(v,u);
		for(int i=1;i<=n;++i) f[i][0]=read();
		dp(1,0); dfs(1); 
		for(int i=1;i<=n;++i) 
		{
			for(int j=1;j<=k;++j) f[i][j]+=f[i][j-1];
			printf("%lld\n",f[i][k]);
		}
		return 0;
	}
}
signed main(){return yspm::main();}

おすすめ

転載: www.cnblogs.com/yspm/p/12611830.html