bzoj 2152: 聪聪可可

点分治时维护出t[0],t[1],t[2],分别表示路径长度%3之后的数量。

答案就是t[0]^2+2*t[1]*t[2]

(能不能依次处理子树呢?????感觉这个题可以。。。。)

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 #define M 10000005
 4 #define LL long long
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 inline int ra()
 8 {
 9     int x=0,f=1; char ch=getchar();
10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
12     return x*f;
13 }
14 int n,K,cnt,sum,ans,root;
15 int head[20005],deep[20005],d[20005],f[20005],size[20005],t[5];
16 bool vis[20005];
17 struct data{int to,next,v;}e[40005];
18 void insert(int x, int y, int v){e[++cnt].next=head[x]; e[cnt].to=y; e[cnt].v=v; head[x]=cnt;}
19 void getroot(int x, int fa)
20 {
21     size[x]=1; f[x]=0;
22     for (int i=head[x];i;i=e[i].next)
23     {
24         if (e[i].to==fa || vis[e[i].to]) continue;
25         getroot(e[i].to,x);
26         size[x]+=size[e[i].to];
27         f[x]=max(f[x],size[e[i].to]);
28     }
29     f[x]=max(f[x],sum-size[x]);
30     if (f[x]<f[root]) root=x;
31 }
32 void getdeep(int x, int fa)
33 {
34     t[d[x]]++;
35     for (int i=head[x];i;i=e[i].next)
36     {
37         if (vis[e[i].to] || e[i].to==fa) continue;
38         d[e[i].to]=(d[x]+e[i].v)%3;
39         getdeep(e[i].to,x);
40     }
41 }
42 int cal(int x, int tot)
43 {
44     d[x]=tot; 
45     memset(t,0,sizeof(t));
46     getdeep(x,0);
47     return t[0]*t[0]+t[1]*t[2]*2;
48 }
49 void solve(int x)
50 {
51     ans+=cal(x,0); vis[x]=1;
52     for (int i=head[x];i;i=e[i].next)
53     {
54         if (vis[e[i].to]) continue;
55         ans-=cal(e[i].to,e[i].v);
56         sum=size[e[i].to]; root=0;
57         getroot(e[i].to,0);
58         solve(root);
59     }
60 }
61 int main()
62 {
63     n=ra();
64     for (int i=1; i<n; i++)
65     {
66         int x=ra(),y=ra(),v=ra()%3;
67         insert(x,y,v); insert(y,x,v); 
68     }
69     sum=n; f[0]=inf;
70     getroot(1,0); 
71     solve(root);
72     int t=__gcd(ans,n*n);
73     printf("%d/%d\n",ans/t,n*n/t);
74     return 0;
75 }

 

posted @ 2017-02-20 14:03  ws_ccd  阅读(151)  评论(0编辑  收藏  举报