题意

一棵树,给定边权,求满足两点之间的路径上权值和为3的倍数的点对数量.

分析

点分治板题,对每个重心求子树下面的到根的距离模3分别为0,1,2的点的个数就行了.

O(3nlogn)O(3nlogn)O(3nlogn)

CODE

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. char cb[1<<15],*cs=cb,*ct=cb;
  4. #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
  5. template<class T>inline void read(T &res) {
  6. char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
  7. for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
  8. }
  9. const int MAXN = 20005;
  10. int n, fir[MAXN], cnt; bool ban[MAXN];
  11. struct edge{ int to, nxt, w; }e[MAXN<<1];
  12. inline void link(int u, int v, int wt) {
  13. e[++cnt] = (edge){ v, fir[u], wt }, fir[u] = cnt;
  14. e[++cnt] = (edge){ u, fir[v], wt }, fir[v] = cnt;
  15. }
  16. int Get_Size(int x, int ff) { //求SIZE
  17. int re = 1;
  18. for(int v, i = fir[x]; i; i = e[i].nxt)
  19. if(!ban[v=e[i].to] && v != ff) re += Get_Size(v, x);
  20. return re;
  21. }
  22. int Get_Root(int x, int ff, int Size, int &G) { //找重心
  23. int re = 1; bool flg = true;
  24. for(int v, i = fir[x]; i; i = e[i].nxt)
  25. if(!ban[v=e[i].to] && v != ff) {
  26. int temp = Get_Root(v, x, Size, G);
  27. if(temp<<1 > Size) flg = false;
  28. re += temp;
  29. }
  30. if(Size-re<<1 > Size) flg = false;
  31. if(flg) G = x;
  32. return re;
  33. }
  34. int now[3], tmp[3], Ans;
  35. void Count(int x, int ff, int dis) {
  36. ++tmp[dis];
  37. for(int v, i = fir[x]; i; i = e[i].nxt)
  38. if(!ban[v=e[i].to] && v != ff) Count(v, x, (dis+e[i].w)%3);
  39. }
  40. inline void Solve(int x) { //算答案
  41. now[0] = now[1] = now[2] = 0;
  42. for(int v, i = fir[x]; i; i = e[i].nxt)
  43. if(!ban[v=e[i].to]) {
  44. tmp[0] = tmp[1] = tmp[2] = 0;
  45. Count(v, x, e[i].w);
  46. Ans += tmp[0] * now[0] << 1;
  47. Ans += tmp[1] * now[2] << 1;
  48. Ans += tmp[2] * now[1] << 1;
  49. now[0] += tmp[0];
  50. now[1] += tmp[1];
  51. now[2] += tmp[2];
  52. }
  53. Ans += (now[0]<<1) + 1;
  54. }
  55. void TDC(int x) { //点分治
  56. int Size = Get_Size(x, 0);
  57. Get_Root(x, 0, Size, x);
  58. Solve(x); ban[x] = 1; //打标记
  59. for(int v, i = fir[x]; i; i = e[i].nxt)
  60. if(!ban[v=e[i].to]) TDC(v);
  61. }
  62. int main() {
  63. read(n);
  64. for(int i = 1, x, y, z; i < n; ++i)
  65. read(x), read(y), read(z), link(x, y, z%3);
  66. TDC(1);
  67. int d = Ans ? __gcd(Ans, n*n) : 1;
  68. printf("%d/%d\n", Ans/d, n*n/d);
  69. }

UpdUpdUpd…sb了…直接树形DP不就完事了… O(3n)O(3n)O(3n)

CODE

(粘来的代码)

  1. // luogu-judger-enable-o2
  2. #include<cstdio>
  3. #include<cctype>
  4. #define maxn 20005
  5. char cb[1<<15],*cs,*ct;
  6. #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
  7. inline void read(int &a){
  8. char c;while(!isdigit(c=getc()));
  9. for(a=c-'0';isdigit(c=getc());a=a*10+c-'0');
  10. }
  11. int n,ans,f[maxn][3],g[3];
  12. int fir[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],tot;
  13. inline void line(int x,int y,int z){nxt[++tot]=fir[x];fir[x]=tot;to[tot]=y;w[tot]=z;}
  14. void dfs(int u,int pre){
  15. f[u][0]=1;
  16. for(int i=fir[u],v;i;i=nxt[i]) if((v=to[i])!=pre){
  17. dfs(v,u);
  18. for(int j=0;j<3;j++) g[(j+w[i])%3]=f[v][j];
  19. for(int j=0;j<3;j++) ans+=f[u][j]*g[j?3-j:0],f[u][j]+=g[j];
  20. }
  21. }
  22. int gcd(int a,int b){return b?gcd(b,a%b):a;}
  23. int main()
  24. {
  25. #ifndef ONLINE_JUDGE
  26. freopen("H.in","r",stdin);
  27. #endif
  28. read(n);
  29. for(int i=1,x,y,z;i<n;i++) read(x),read(y),read(z),line(x,y,z),line(y,x,z);
  30. dfs(1,0);
  31. ans=ans*2+n;
  32. int d=gcd(ans,n*n);
  33. printf("%d/%d",ans/d,n*n/d);
  34. }

BZOJ 2152 / Luogu P2634 [国家集训队]聪聪可可 (点分治/树形DP)的更多相关文章

  1. luogu P2634 [国家集训队]聪聪可可 点分治

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

  2. BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)

    题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...

  3. [BZOJ2152]聪聪可可 点分治/树形dp

    2152: 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MB Submit: 3602  Solved: 1858 [Submit][Status][Discu ...

  4. [LUOGU] P2634 [国家集训队]聪聪可可

    点分治裸题,甚至不需要栈回撤. 尝试用容斥写了一波,就是把所有子树混一块计算,最后减去子树内路径条数. #include<iostream> #include<cstring> ...

  5. bzoj2152 / P2634 [国家集训队]聪聪可可(点分治)

    P2634 [国家集训队]聪聪可可 淀粉质点分治板子 边权直接 mod 3 直接点分治统计出所有的符合条件的点对再和总方案数约分 至于约分.....gcd搞搞就好辣 #include<iostr ...

  6. 洛谷 P2634 [国家集训队]聪聪可可 解题报告

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

  7. 洛谷 P2634 [国家集训队]聪聪可可-树分治(点分治,容斥版) +读入挂+手动O2优化吸点氧才过。。。-树上路径为3的倍数的路径数量

    P2634 [国家集训队]聪聪可可 题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

  8. P2634 [国家集训队]聪聪可可(题解)(点分治)

    P2634 [国家集训队]聪聪可可(题解)(点分治) 洛谷题目 #include<iostream> #include<cstdlib> #include<cstdio& ...

  9. 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...

随机推荐

  1. Second largest node in the BST

    Find the second largest node in the BST 分析: 如果root有右节点,很明显第二大的node有可能在右子树里.唯一不满足的条件就是右子树只有一个node. 这个 ...

  2. Less学习(1)

    写在开头的话: 月余前被问起会不会Less,当时就有想学这个css框架的念头,而在昨天,在前端乱炖上看到一篇LessCss的开篇介绍,忽然就有了一股立马去学的冲动,回到家后找了几篇文章看了下,初感觉比 ...

  3. hadoop集群搭建及易踩坑收录

    配置前先把域名映射配好哈 详情参考我的其他随笔(哪里不通可以在下方评论) 下载好hdfs.tar.gz 后 在/home/ldy下 mkdir apps/ tar -xzvf hdfs.tar.gz  ...

  4. SQLite基础-6.运算符

    目录 SQLite 运算符 1. 运算符 2. 算数运算符 3. 比较运算符 4. 逻辑运算符 SQLite 运算符 1. 运算符 首先,问大家运算符是什么?运算符在很多领域均用使用.它也分很多中,常 ...

  5. vue 评论 computed watch 分隔符 局部组件 全局组件 子传父消息|父传子消息

    评论案例 splice: (start 几位,替换(新增)内容) splice(0,0,内容)在头部插入内容 splice(0,1) 把索引为0的往后删除1位  splice(0,1,内容)把索引为0 ...

  6. MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到。要想鼠标不按下时的移动也能捕捉到,需要setMouseTracking(true)

    最近用Qt软件界面,需要用到mouseMoveEvent,研究了下,发现些问题,分享一下. 在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent,但是MouseMoveEvent为了不太耗资 ...

  7. redis 学习(18)-- AOF

    redis -- AOF 什么是 AOF 通过日志方式将redis中的写命令进行日志记录,保存在硬盘文件中. 日志记录的实质是将写命令写在硬盘的缓冲区中,再根据相关策略把数据刷新到磁盘中. 当redi ...

  8. 在react项目当中做导航守卫

    距离上一篇文章,似乎已经过去好久了. 确实是最近相对忙了一点,本身是用vue重构之前一个传统的项目,就自己一个人写.而且,在稍微闲暇之余,想着同时用react也重构一遍,也算是对react的学习吧!毕 ...

  9. 03docker镜像

    docker的镜像操作 Union文件系统是Docker镜像的基础. UnionFS(联合文件系统):Union文件系统是一种分层,轻量级并且高性能的文件系统.它支持对文件系统的修改作为一次提交来一层 ...

  10. bash 中 () {} [] [[]] (()) 的解释

    bash 中 () {} [] [[]] (()) 的解释 来源  https://www.cnblogs.com/fhefh/archive/2011/04/16/2017895.html bash ...