bzoj2152
题解:
随便点分治,用一个t数组,t[i]代表有u到root的值mod3==i; 那么答案就是:t[0]*t[0]+t[1]*t[2]*2;
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define N 20005 using namespace std; int pre[N*2],now[N],v[N*2],val[N*2]; int d[N],son[N],f[N]; int t[4]; bool vis[N]; int tot,all,n,ans,root; int read() { int x=0; char ch; bool bo=0; while (ch=getchar(), ch<'0'||ch>'9') if (ch=='-') bo=1; while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); if (bo) return -x; return x; } void ins(int a,int b,int c) { ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c; } int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } void getroot(int u,int fa) { son[u]=1; f[u]=0; for (int p=now[u]; p; p=pre[p]) { int vv=v[p]; if (vv==fa || vis[vv]) continue; getroot(vv,u); son[u]+=son[vv]; f[u]=max(f[u],son[vv]); } f[u]=max(f[u],all-son[u]); if (f[u]<f[root]) root=u; } void getarray(int u,int fa) { t[d[u]]++; for (int p=now[u]; p; p=pre[p]) { int vv=v[p]; if (vv==fa||vis[vv]) continue; d[vv]=(d[u]+val[p])%3; getarray(vv,u); } } int calc(int u,int value) { t[0]=t[1]=t[2]=0; d[u]=value; getarray(u,0); return t[0]*t[0]+t[1]*t[2]*2; } void solve(int u) { ans+=calc(u,0); vis[u]=1; for (int p=now[u]; p; p=pre[p]) { int vv=v[p]; if (vis[vv]) continue; ans-=calc(vv,val[p]); root=0; all=son[vv]; getroot(vv,0); solve(root); } } int main() { n=read(); for (int i=1; i<n; i++) { int a=read(),b=read(),val=read()%3; ins(a,b,val); ins(b,a,val); } ans=0; f[root=0]=all=n; getroot(1,0); solve(root); int kk=gcd(ans,n*n); printf("%d/%d\n",ans/kk,n*n/kk); }
我太蒟蒻了,所以神犇们留下意见让我跪膜