Cattle-off practice match 60 E. matched opponents tree heuristics [merger]

Portal

answer

All this statistical sub-tree problem is certainly possible to do merger with tree heuristic.
Preprocessing the distance to each point, the son of the root node and heavy.
Then start doing heuristic merger, the key is how the statistical answer to each node.
Here I refer to the idea of partition point processing, statistics for each node before the answer, I have all the information that a sub-tree, and then I tried to get a complete traversal of its sub-tree, the sub-tree Fengyun All nodes are taken out, and statistics about the answer, then it is added after the completion of the statistical count of an array, so you can avoid the calculation with a sub-point of the tree. In fact, conventional statistical methods dotted governance.
When coming back to the parent, if the point is the son of light, then directly to the array count all the information can be cleared, of course, not memset, to traverse it. If this point is re-son, do not forget about itself should also be counted.

Code

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <queue>
#define xx first
#define yy second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int inf=0x3f3f3f3f;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int N=3e5+10;
const int M=1e6+10;
int n,k,a[N],dep[N],siz[N],son[N];
LL ans[N],temp[N],cnt,suma[N],depcnt[N];
int head[N],to[N*2],nxt[N*2],tot;
void add(int u,int v) {to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}

void predfs(int u,int fa){
	siz[u]=1;dep[u]=dep[fa]+1;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa) continue;
		predfs(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}

void getnode(int u,int fa){
	temp[++cnt]=u;
	for(int i=head[u];i;i=nxt[i]) if(to[i]!=fa) getnode(to[i],u);
}

void clear(int u,int fa){
	suma[dep[u]]=depcnt[dep[u]]=0;
	for(int i=head[u];i;i=nxt[i]) if(to[i]!=fa) clear(to[i],u);
}

void dfs(int u,int fa,bool keep){
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa||v==son[u]) continue;
		dfs(v,u,false);
	}
	if(son[u]) dfs(son[u],u,true);
	for(int ii=head[u];ii;ii=nxt[ii]){
		int v=to[ii];
		if(v==fa||v==son[u]) continue;
		cnt=0;
		getnode(v,u);
		for(int i=1;i<=cnt;i++)
			if(dep[temp[i]]-dep[u]<k){
				int depv=k+2*dep[u]-dep[temp[i]];
				ans[u]+=suma[depv]+depcnt[depv]*a[temp[i]];
			}
		for(int i=1;i<=cnt;i++) suma[dep[temp[i]]]+=a[temp[i]],depcnt[dep[temp[i]]]++;
	}
	suma[dep[u]]+=a[u],depcnt[dep[u]]++;
	if(!keep) clear(u,fa);
}

int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1,u,v;i<n;i++){
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	predfs(1,0);
	dfs(1,0,true);
	for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
	return 0;
} 

Tucao about DD velocity vector, the best chain-Star forward honestly with it.

Guess you like

Origin www.cnblogs.com/BakaCirno/p/12604767.html