虽然过了,但用时 1.99s 比平均速度慢二十被,喜提最裂解。我的点分治哪里慢了?
#include<bits/stdc++.h>
#define N 20000
#define EL(x,y,z) ((el){(x),(y),(z)})
using namespace std;
struct el{
int x,y,z;
inline void ad(){x++;}
el operator +(el a)
{return EL(x+a.x,y+a.y,z+a.z);}
inline void debug()
{printf("[%d %d %d]\n",x,y,z);}
};
struct ljb{
int en,v[2*N+5],w[2*N+5],fst[N+5],nxt[2*N+5];
inline void add(int x,int y,int z)
{
en++;
v[en]=y;
w[en]=z;
nxt[en]=fst[x];
fst[x]=en;
}
};
ljb g;
bool vis[N+5];
int n,sz[N+5];
//树的重心
inline int zzp_gets_cxc(int x,int f,int sum)
{
sz[x]=1;
int res=0;
for(int i=g.fst[x];i;i=g.nxt[i])
if(g.v[i]!=f&&!vis[g.v[i]])
{
res=max(res,zzp_gets_cxc(g.v[i],x,sum));
sz[x]+=sz[g.v[i]];
}
if(sz[x]>=sum/2) return x;
return res;
}
inline el getel(int x,int f,int z)
{
el res=EL(0,0,0);
if(z%3==0) res.x++;
if(z%3==1) res.y++;
if(z%3==2) res.z++;
for(int i=g.fst[x];i;i=g.nxt[i])
if(g.v[i]!=f&&!vis[g.v[i]])
res=res+getel(g.v[i],x,z+g.w[i]);
return res;
}
inline int dfs(int x,int f)
{
// cout<<'('<<x<<"):\n";
vis[x]=1;
int res=0;
el tot=EL(0,0,0);
for(int i=g.fst[x];i;i=g.nxt[i])
if(g.v[i]!=f&&!vis[g.v[i]])
{
int v=g.v[i];
el now=getel(v,x,g.w[i]);
res+=now.x+now.x*tot.x+now.y*tot.z+now.z*tot.y;
tot=tot+now;
// tot.debug();
}
for(int i=g.fst[x];i;i=g.nxt[i])
if(g.v[i]!=f&&!vis[g.v[i]])
{
int v=g.v[i];
int r=zzp_gets_cxc(v,x,sz[v]);
zzp_gets_cxc(r,0,sz[v]);
res+=dfs(r,x);
}
return res;
}
inline int gcd(int x,int y)
{
if(y==0) return x;
return gcd(y,x%y);
}
int main()
{
cin>>n;
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
g.add(x,y,z);
g.add(y,x,z);
}
// cout<<zzp_gets_cxc(1,0,n);
int ans=2*dfs(zzp_gets_cxc(1,0,n),0)+n;
cout<<ans/gcd(ans,n*n)<<'/'<<n*n/gcd(ans,n*n);
return 0;
}