对f和g数组分别开一个内存池就只有20分
只开一个,两个数组一起用就能过???
求dalao解释QWQ
(在学长链剖分之前,基本没写过指针。。。
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N=1e5+10;
int tot; ll ans;
int fir[N],leaf[N],son[N];
ll buf[4*N];
ll *f[N],*g[N],*now=buf;
struct edge
{
int to;
int nxt;
}e[2*N];
inline void add(int x,int y)
{
e[++tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot;
e[++tot].to=x; e[tot].nxt=fir[y]; fir[y]=tot;
}
inline void newnode(int p)
{
//就是这里
f[p]=now,now+=2*leaf[p];
g[p]=now,now+=2*leaf[p];
//如果把这两行改成下面这样就会错
f[p]=now1,now1+=2*leaf[p];
g[p]=now2,now2+=2*leaf[p];
}
inline void dfs1(int p,int fa)
{
for(int i=fir[p];i;i=e[i].nxt)
{
int q=e[i].to;
if(q==fa) continue;
dfs1(q,p);
if(leaf[q]>leaf[son[p]]) son[p]=q;
}
leaf[p]=leaf[son[p]]+1;
}
inline void dfs2(int p,int fa)
{
if(son[p])
{
f[son[p]]=f[p]+1;
g[son[p]]=g[p]-1;
dfs2(son[p],p);
}
f[p][0]=1,ans+=g[p][0];
for(int i=fir[p];i;i=e[i].nxt)
{
int q=e[i].to;
if(q==fa||q==son[p]) continue;
newnode(q),dfs2(q,p);
for(int j=1;j<=leaf[q]+1;j++)
{
if(j<=leaf[q]) ans+=g[q][j]*f[p][j-1];
ans+=f[q][j-1]*g[p][j];
}
for(int j=1;j<=leaf[q]+1;j++)
{
if(j<=leaf[q]) g[p][j-1]+=g[q][j];
g[p][j]+=f[q][j-1]*f[p][j];
f[p][j]+=f[q][j-1];
}
}
}
int main()
{
int n,a,b;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
}
dfs1(1,0);
newnode(1),dfs2(1,0);
printf("%lld\n",ans);
return 0;
}