BZOJ 2152 聪聪可可 树的点分治
来源:互联网 发布:js是什么文件可以执行 编辑:程序博客网 时间:2024/05/22 00:53
题目大意:有两个小孩在玩游戏,他们每一个人在树中取一个点,如果这两个点之间的路径长度之和是3的倍数,那么聪聪就赢了,否则他就输了。给出这棵树,求聪聪赢的概率,答案用分数表示。
思路:数据范围2w,肯定不能枚举点然后LCA。所以就只能点分治了。这还是一道比较常规的点分治问题,但是有一个地方需要注意,在统计两点之间的距离的时候我一开始的想法是直接n^2的枚举,然后记录。但是那样时间复杂度就会严重退化。但是注意到我们只需要%3==0的数的个数,和这个有关的之后%3==0,%3==1,%3==2的数。所以在统计的时候我们只要统计这三种数字的个数就可以了。
PS:用了algorithm中的__gcd函数,据说考试的时候不让用。。。
CODE:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 20010#define INF 0x3f3f3f3fusing namespace std;int points;int head[MAX],total;int next[MAX << 1],aim[MAX << 1],length[MAX << 1];int size[MAX],_size,_total,c;bool v[MAX];int cnt[MAX],dis[3],p;inline void Add(int x,int y,int len){next[++total] = head[x];aim[total] = y;length[total] = len % 3;head[x] = total;}inline void GetRoot(int x,int last){size[x] = 1;int max_size = 0;for(int i = head[x]; i; i = next[i]) {if(aim[i] == last || v[aim[i]])continue;GetRoot(aim[i],x);size[x] += size[aim[i]];max_size = max(max_size,size[aim[i]]);}max_size = max(max_size,_total - size[x]);if(_size > max_size)_size = max_size,c = x;}inline void GetDis(int x,int last,int len){++dis[len % 3];for(int i = head[x]; i; i = next[i]) {if(aim[i] == last || v[aim[i]])continue;GetDis(aim[i],x,len + length[i]);}}inline int Count(int x,int len){int re = 0;p = 0;memset(dis,0,sizeof(dis));GetDis(x,0,len);re += dis[0] * dis[0];re += dis[1] * dis[2] << 1;return re;}inline void Work(int x){_size = INF;_total = size[x] ? size[x]:points;GetRoot(x,0);x = c;v[x] = true;cnt[x] = Count(x,0);for(int i = head[x]; i; i = next[i]) {if(v[aim[i]])continue;cnt[x] -= Count(aim[i],length[i]);Work(aim[i]);}}int main(){cin >> points;for(int x,y,z,i = 1; i < points; ++i) {scanf("%d%d%d",&x,&y,&z);Add(x,y,z),Add(y,x,z);}Work(1);int ans = 0;for(int i = 1; i <= points; ++i)ans += cnt[i];cout << ans / __gcd(ans,points * points) << '/' << points * points / __gcd(ans,points * points) << endl;return 0;}
0 0
- BZOJ 2152 聪聪可可 树的点分治
- bzoj 2152: 聪聪可可(树的点分治)
- 【bzoj 2152】聪聪可可(树的点分治)
- 【BZOJ】2152: 聪聪可可 点分治
- bzoj 2152: 聪聪可可 点分治
- 【BZOJ 2152】聪聪可可 点分治
- Bzoj 2152: 聪聪可可(点分治)
- BZOJ 2152: 聪聪可可 点分治
- 【BZOJ】2152 聪聪可可 点分治
- BZOJ 2152: 聪聪可可 点分治
- BZOJ 2152: 聪聪可可 点分治/树dp
- BZOJ 2152 聪聪可可 树的点分治/树形DP
- BZOJ 题目2152: 聪聪可可(树的点分治)
- 【树分治】 BZOJ 2152 聪聪可可
- BZOJ 2152: 聪聪可可 树分治
- bzoj 2152 聪聪可可(点分治)
- BZOJ 2152 聪聪可可 (树上点分治)
- [bzoj 2152] 聪聪可可 树上点分治
- java中String初始化的两种方式
- 【getline】#70 A. Haiku
- 【干货】国外程序员整理的 C++ 资源大全
- 【SonicUI】最可能的异常: Microsoft C++ 异常: 内存位置 0x0011f280 处的 char。
- 试论述OSI参考模型和TCP/IP模型的异同和特点
- BZOJ 2152 聪聪可可 树的点分治
- 第9周项目6三色球问题
- textview的自定义实现
- 闭包(closure)与协程共用时要注意的事情
- 编程札记
- 翻转链表
- struct stat结构体简介
- 利用私钥创建公钥
- 试简述分组交换的要点