如题,不知道为什么对于两个 dp 数组分别开一个内存池就错误,而共用一个就是对的。
#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 求大佬解答疑问)