对于长链剖分开空间的疑问
查看原帖
对于长链剖分开空间的疑问
128591
Refined_heart楼主2021/7/25 19:48

如题,不知道为什么对于两个 dpdp 数组分别开一个内存池就错误,而共用一个就是对的。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=1e6+10;
int head[MAXN],tot,n;
int pa[MAXN],len[MAXN],son[MAXN];
int *g[MAXN];
int *f[MAXN],tmp[MAXN],*pos=tmp;
int ans;
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		s=s*10-48+ch;
		ch=getchar();
	}
	return s*w;
}
struct E{int nxt,to;}e[MAXN];
inline void add(int x,int y){e[++tot]=(E){head[x],y};head[x]=tot;}
void dfs1(int x,int faa){
	pa[x]=faa;
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==faa)continue;
		dfs1(j,x);
		if(len[j]>len[son[x]])son[x]=j;
	}
	len[x]=len[son[x]]+1;
}
void dp(int x){
	f[x][0]=1;
	if(son[x]){
		f[son[x]]=f[x]+1;
		g[son[x]]=g[x]-1;
		dp(son[x]);
	}
	ans+=g[x][0];
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==son[x]||v==pa[x])continue;
		f[v]=pos;pos+=(len[v]<<1);
		g[v]=pos;pos+=(len[v]<<1);
		dp(v);
		for(int j=0;j<len[v];++j){
			if(j)ans+=f[x][j-1]*g[v][j];
			ans+=f[v][j]*g[x][j+1];
		}
		for(int j=0;j<len[v];++j){
			g[x][j+1]+=f[x][j+1]*f[v][j];
			if(j)g[x][j-1]+=g[v][j];
			f[x][j+1]+=f[v][j];
		}
	}
}
signed main(){
	n=read();
	for(int i=1;i<n;++i){
		int u=read();
		int v=read();
		add(u,v);add(v,u);
	}
	dfs1(1,0);
	f[1]=pos;pos+=(len[1]<<1);
	g[1]=pos;pos+=(len[1]<<1);
	dp(1);printf("%lld\n",ans);
	return 0;
}

看到了讨论的最后一个,根据那位双内存池的写法,答案不再错误了却又发生了奇怪的 RE 问题,无论怎么改空间结果都是 RE 和 MLE 求大佬解答疑问)

2021/7/25 19:48
加载中...