• 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
    ",ans/t,n*n/t);
    74     return 0;
    75 }
  • 相关阅读:
    3dsmax不同版本 pyside qt UI 设置max窗口为父窗口的方法
    oracle中的数据库和实例
    oracle中的表空间(tablespace)、方案(schema)、段(segment)、区(extent)、块(block)
    什么是WSE
    Server.Transfer,Response.Redirect的区别
    Oracle 中的几个数据类型介绍
    oracle中的连接字符串
    Oracle中的 单引号 和 双引号
    接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?
    聚簇索引
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6419236.html
Copyright © 2020-2023  润新知