版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Love_mona/article/details/81283414
蒟蒻的垂死挣扎
这道题一样是模板题,在树上大力点分一波,记录权值和mod 3的路径条数,每次计算贡献即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define MOD 998244353
#define N 20010
#define M 10001000
#define RG register
using namespace std;
inline ll read(){
RG ll x=0,o=1; RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=((x<<3)+(x<<1))+ch-'0',ch=getchar();
return x*o;
}
int n,root,top,t1[4],t2[4],first[N],Max=1e9,siz[N],Siz,vis[N],ans,st[N],tot;
struct mona { int nxt,en; int w; } s[N<<1];
inline void Insert(int x,int y,int w) { s[++top]=(mona) { first[x],y,w },first[x]=top; }
inline int Gcd(int x,int y) { while(y^=x^=y^=x%=y); return x; }
inline void Getroot(int k,int fa){
siz[k]=1; int mmax=0;
for(RG int i=first[k];i;i=s[i].nxt){
int en=s[i].en; if(en==fa||vis[en]) continue ;
Getroot(en,k),siz[k]+=siz[en],mmax=max(mmax,siz[en]);
} mmax=max(mmax,Siz-siz[k]);
if(mmax<Max) Max=mmax,root=k; return ;
}
inline void Getdis(int k,int fa,int D){
int now=D%3;
++t2[now],ans+=t1[ (now!=0) ? (3-now):0 ];
for(RG int i=first[k];i;i=s[i].nxt){
int en=s[i].en; if(en==fa||vis[en]) continue ;
Getdis(en,k,D+s[i].w);
} return ;
}
inline void Divide(int k){
vis[k]=1; for(RG int i=0;i<=2;++i) t1[i]=0;
for(RG int i=first[k];i;i=s[i].nxt){
int en=s[i].en; if(vis[en]) continue ;
for(RG int j=0;j<=2;++j) t2[j]=0; Getdis(s[i].en,0,s[i].w);
for(RG int j=0;j<=2;++j) t1[j]+=t2[j];
} ans+=t1[0];
for(RG int i=first[k];i;i=s[i].nxt){
int en=s[i].en; if(vis[en]) continue ;
Siz=(siz[k]>=siz[en])?siz[en]:Siz-siz[k];
Max=1e9,root=0,Getroot(en,0),Divide(root);
}
}
int main(){
n=Siz=read();
for(RG int i=1;i<n;++i){
int x=read(),y=read(),z=read();
Insert(x,y,z),Insert(y,x,z);
} Getroot(1,0),Divide(root); ans<<=1,ans+=n;
int gcd=Gcd(ans,n*n);
cout<<ans/gcd<<'/'<<n*n/gcd;
}