http://www.lydsy.com/JudgeOnline/problem.php?id=2152 (题目链接)

题意

  给出一棵n个节点的带权树,求有多少点对的距离是3的倍数。

solution

  点分治。对于每个重心统计出每棵子树到重心的距离%3=0/1/2的点的数量即可。求出ans后与n²进行下gcd出解。

  许久之后回来复习了一下,发现点分治的关键其实就是在如何处理经过重心的情况上,每道题的做法都不同,有时候还会有很神奇的方法水过。。。

代码

  1. // bzoj2152
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. #define MOD 1000000007
  9. #define inf 2147483640
  10. #define LL long long
  11. #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
  12. using namespace std;
  13. inline int getint() {
  14. int x=0,f=1;char ch=getchar();
  15. while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
  16. while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
  17. return x*f;
  18. }
  19.  
  20. const int maxn=20010;
  21. struct edge {int next,to,w;}e[maxn<<2];
  22. int head[maxn],d[maxn],t[10],f[maxn],vis[maxn],son[maxn],sum,ans1,ans2,cnt,root,n;
  23.  
  24. void insert(int u,int v,int w) {
  25. e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
  26. e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;
  27. }
  28. void init() {
  29. ans1=cnt=sum=root=0;
  30. scanf("%d",&n);
  31. for (int i=1;i<n;i++) {
  32. int u=getint(),v=getint(),w=getint()%3;
  33. insert(u,v,w);
  34. }
  35. ans2=n*n;
  36. }
  37. void calroot(int u,int fa) {
  38. son[u]=1;f[u]=0;
  39. for (int i=head[u];i;i=e[i].next) {
  40. if (vis[e[i].to] || e[i].to==fa) continue;
  41. calroot(e[i].to,u);
  42. son[u]+=son[e[i].to];
  43. f[u]=max(f[u],son[e[i].to]);
  44. }
  45. f[u]=max(f[u],sum-son[u]);
  46. if (f[u]<f[root]) root=u;
  47. }
  48. void caldeep(int u,int fa) {
  49. t[d[u]]++;
  50. for (int i=head[u];i;i=e[i].next) {
  51. if (vis[e[i].to] || e[i].to==fa) continue;
  52. d[e[i].to]=(d[u]+e[i].w)%3;
  53. caldeep(e[i].to,u);
  54. }
  55. }
  56. int cal(int u,int now) {
  57. t[0]=t[1]=t[2]=0;
  58. d[u]=now;caldeep(u,0);
  59. return t[1]*t[2]*2+t[0]*t[0];
  60. }
  61. void work(int u) {
  62. ans1+=cal(u,0);
  63. vis[u]=1;
  64. for (int i=head[u];i;i=e[i].next) if (!vis[e[i].to]) {
  65. ans1-=cal(e[i].to,e[i].w);
  66. sum=son[e[i].to];
  67. root=0;
  68. calroot(e[i].to,0);
  69. work(root);
  70. }
  71. }
  72. int gcd(int a,int b) {
  73. return a%b==0?b:gcd(b,a%b);
  74. }
  75. int main() {
  76. init();
  77. sum=n;f[0]=inf;
  78. calroot(1,0);
  79. work(root);
  80. int x=gcd(ans1,ans2);
  81. printf("%d/%d",ans1/x,ans2/x);
  82. return 0;
  83. }

  

【bzoj2152】 聪聪可可的更多相关文章

  1. 【BZOJ2152】聪聪可可(点分治)

    [BZOJ2152]聪聪可可(点分治) 题面 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电 ...

  2. BZOJ2152 [国家集训队] 聪聪可可 [点分治]

    题目传送门 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 5237  Solved: 2750[Submit][Status][Discuss ...

  3. BZOJ2152 聪聪可可 【点分治】

    BZOJ2152 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问 ...

  4. 【bzoj2152】聪聪可可 点分治

    [bzoj2152]聪聪可可 2014年9月7日3,5472 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是 ...

  5. BZOJ2152 聪聪可可 (点分治)

    2152: 聪聪可可 题意: 在一棵边带权的树中,问任取两个点,这两个点间的权值和是3的倍数的概率. 思路: 经典的点分治题目. 利用点分治在计算所有路径长度,把路径长度对3取模,用t[0],t[1] ...

  6. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  7. C++之路进阶——bzoj2152(聪聪可可)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...

  8. bzoj2152 聪聪可可

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  9. 【BZOJ2152】聪聪可可

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  10. BZOJ2152[国家集训队]聪聪可可——点分治

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

随机推荐

  1. f2fs中node page的lock_page

    [都是思想片段, 待好好整理] node page的lock_page首先是为了改变page的状态:set_page_dirty, 还有set_nid操作时也会设置父节点的nid, 但是这样设置nod ...

  2. [转]一篇很全面的freemarker教程

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  3. NOI2018准备Day19

    5天没写. 伸展树  主席树 3到线段树模板题

  4. c++ 头文件

    可以将程序分为二部分: 头文件:包含结构声明和使用这些结构的函数的原型 源代码文件: 包含与结构有关的函数的代码 不要将函数的定义或变量的声明放在头文件里, 一般头文件可以包含以下内容 >函数原 ...

  5. 常用 redis 命令(for php)

    Redis 主要能存储 5 种数据结构,分别是 strings,hashes,lists,sets 以及 sorted sets. 新建一个 redis 数据库 $redis = new Redis( ...

  6. C8051逆向电阻屏:头儿拍脑袋说电阻屏IC好赚钱3块钱成本能卖20几块。,一个月不分昼夜逆向成功后头儿说电阻屏已经被市场淘汰请放弃治疗。

    参考: 书籍,<圈圈教你玩USB>  C8051F单片机快速入门:http://www.waveshare.net/Left_Column/C8051F_Application_Notes ...

  7. centos hadoop搭建准备

    永久修改主机名:hostnamectl set-hostname <hostname> IP地址: BOOTPROTO=static IPADDR=192.168.31.128NETMAS ...

  8. Windows Server+AMD GPU+HDMI时_黑边_不铺满问题的解决办法

    HDMI接显示器或电视,有黑边或者被放大了是个很常见的问题,显卡设置界面里改下Scale或者Overscan/Underscan就行,可问题是WindowsServer版的CCC没有控制颜色对比度和缩 ...

  9. C程序中对时间的处理——time库函数详解

    包含文件:<sys/time.h> <time.h> 一.在C语言中有time_t, tm, timeval等几种类型的时间 1.time_t time_t实际上是长整数类型, ...

  10. MSSQL 问题集锦

    [1]关于SQL Server数据库连接字符串的特殊参数说明 MultipleActiveResultSets和Mars_Connection同义,指定此数据库连接是否复用数据库内已建立的相同用户的连 ...