本题中的 g 数组是不是只要一倍空间就可以了
查看原帖
本题中的 g 数组是不是只要一倍空间就可以了
483966
一粒夸克楼主2021/6/26 11:48

[POI2014]HOT-Hotels

代码:

#include<bits/stdc++.h>
using namespace std;
int n,d[5005],dep[5005],son[5005];
int to[10005],ne[10005],h[10005],cnt;
inline void link(int x,int y){
	to[++cnt]=y;
	ne[cnt]=h[x];
	h[x]=cnt;
}
long long *f[5005],*g[5005],p[15005],*o=p,ans;
void dfs(int x,int fa){
	d[x]=d[fa]+1;
	for(int i=h[x];i;i=ne[i]){
		int y=to[i];
		if(y!=fa){
			dfs(y,x);
			if(dep[y]>dep[son[x]])son[x]=y;
		}
	}
	dep[x]=dep[son[x]]+1;
}
void dp(int x,int fa){
	if(son[x])f[son[x]]=f[x]+1,g[son[x]]=g[x]-1,dp(son[x],x);
	f[x][0]=1,ans+=g[x][0];
	for(int i=h[x];i;i=ne[i]){
		int y=to[i];
		if(y!=fa&&y!=son[x]){
			f[y]=o;o+=dep[y]<<1;g[y]=o;o+=dep[y];
			dp(y,x);
			for(int i=0;i<dep[y];i++){
				if(i)ans+=f[x][i-1]*g[y][i];
				ans+=g[x][i+1]*f[y][i];
			}
			for(int i=0;i<dep[y];i++){
				g[x][i+1]+=f[x][i+1]*f[y][i];
				if(i)g[x][i-1]+=g[y][i];
				f[x][i+1]+=f[y][i];
			}
		}
	}
}

int main() {
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		link(x,y);link(y,x);
	}
	dfs(1,1);f[1]=o,o+=dep[1]<<1,g[1]=o,o+=dep[1];
	dp(1,1);
	printf("%lld",ans);
	return 0;
}

我看题解里都是把

  f[y]=o;o+=dep[y]<<1;g[y]=o;o+=dep[y];

写成了

  f[y]=o;o+=dep[y]<<1;g[y]=o;o+=dep[y]<<1;

但向下 dpdp 的时候, ff 指针只会向后走,而不会像 gg 一样向前走,所以是不是没必要在 g[x]g[x]f[son[x]]f[son[x]] 之间留出两倍空间

2021/6/26 11:48
加载中...