【BZOJ 2152】聪聪可可 点分治
对于一棵树,fdrt找到重心,然后分治每个子树。
在一棵以重心为根的树上,符合条件的链是:
1.过重心(根)
2.不过重心
对于1我们只需dfs出距离重心(根)的距离然后统计再减去有重叠的边
对于2我们只需递归处理子树,这样2就分为过子树的根(重心)的链和不过子树根(重心)的链······
这就是点分治啦,貌似边分治更优,但是为了减少代码量,效率什么的我统统都不要(╬▔皿▔)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define read(x) x=getint()
using namespace std;
const int N=20003;
inline const int max( const int &a, const int &b) {return a>b?a:b;}
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
struct node {
int nxt, to, w;
} E[N<<1];
int point[N], size[N], ma[N], n, cnt=0, rt=0, ans=0, table[N], tn, di[N];
bool vis[N];
inline void insect( int x, int y, int z) {
cnt++;
E[cnt].nxt = point[x];
E[cnt].to = y;
E[cnt].w = z;
point[x] = cnt;
}
inline void fdrt( int x, int fa, int s) {
size[x] = 1;
ma[x] = 0;
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to] && E[tmp].to != fa) {
fdrt( E[tmp].to, x, s);
size[x] += size[E[tmp].to];
ma[x] = max( ma[x], size[E[tmp].to]);
}
if ( s - ma[x] > ma[x])
ma[x] = s - ma[x];
if ( ma[x] < ma[rt])
rt = x;
}
inline void mktb( int x, int fa) {
table[ ++tn] = di[x];
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to] && E[tmp].to != fa) {
di[E[tmp].to] = di[x] + E[tmp].w;
mktb( E[tmp].to, x);
}
}
inline int work( int x, int beg) {
int cn0 = 0, cn1 = 0, cn2 = 0;
tn = 0;
di[x] = beg;
mktb( x, -1);
for( int i = 1; i <= tn; ++i) {
switch ( table[i] % 3) {
case 0:
++cn0;
break;
case 1:
++cn1;
break;
case 2:
++cn2;
break;
}
}
return cn0 * cn0 + ( ( cn1 * cn2) << 1);
}
inline void dfs( int x, int s) {
vis[x] = 1;
ans += work( x, 0);
for( int tmp = point[x], ss; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to]) {
ans -= work( E[tmp].to, E[tmp].w);
if ( size[E[tmp].to] > size[x])
ss = s - size[x];
else
ss = size[E[tmp].to];
rt = 0;
fdrt( E[tmp].to, x, ss);
dfs( rt, ss);
}
}
inline int gcd( int x, int y) {
int r = x % y;
while ( r) {
x = y;
y = r;
r = x % y;
}
return y;
}
int main() {
read( n);
int u, v, e;
for( int i = 1; i < n; ++i) {
read( u);
read( v);
read( e);
e %= 3;
insect( u, v, e);
insect( v, u, e);
}
ma[0] = n+3;
memset( vis, 0, sizeof(vis));
fdrt( (n+1)>>1, -1, n);
dfs( rt, n);
int m = n * n, tong = gcd( ans, m);
printf( "%d/%d\n", ans / tong, m / tong);
return 0;
}
点分治完成啦,找重心估计s时偷了点懒效率立刻就低了∑(っ °Д °;)っ还是改回来了
还有我的码风这次有点奇怪⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄.是不是不再像以前那么挤了ヾ (o ° ω ° O ) ノ゙
【BZOJ 2152】聪聪可可 点分治的更多相关文章
- 洛谷 P2634 BZOJ 2152 【模板】点分治(聪聪可可)
题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...
- 【BZOJ 2152】 聪聪可可
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2152 [算法] 点分治 [代码] #include<bits/stdc++.h ...
- [bzoj2152][聪聪和可可] (点分治+概率)
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
- BZOJ 2152:聪聪可可(树上点分治)
题目链接 题意 中文题意. 思路 和上一题类似,只不过cal()函数需要发生变化. 题目中要求是3的倍数,那么可以想到 (a + b) % 3 == 0 和 (a % 3 + b % 3) % 3 = ...
- 「BZOJ 2152」聪聪可可
题目链接 戳这 \(Solution\) 这道题看起来就像点分治对吧.没错就是点分治. 什么是点分治 如果你不会点分治,可以去看看这儿 现在看到这里,首先确保你已经会了点分治,如果不会你还往下看,听不 ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
- 【BZOJ】2152: 聪聪可可(点分治)
http://www.lydsy.com/JudgeOnline/problem.php?id=2152 随便点分..... 只是我在考虑一个地方逗乐.. 当路径长度mod3=0的点数直接乘起来就好. ...
- BZOJ 2152: 聪聪可可 点分治
2152: 聪聪可可 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php ...
- bzoj 2152: 聪聪可可 树的点分治
2152: 聪聪可可 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 485 Solved: 251[Submit][Status] Descripti ...
随机推荐
- 【转】selenium学习路线
selenium学习路线 配置你的测试环境,真对你所学习语言,来配置你相应的selenium 测试环境.selenium 好比定义的语义---“问好”,假如你使用的是中文,为了表术问好,你的写法是“你 ...
- STL vector
STL vector vector是线性容器,它的元素严格的按照线性序列排序,和动态数组很相似,和数组一样,它的元素存储在一块连续的存储空间中,这也意味着我们不仅可以使用迭代器(iterator)访问 ...
- MSDN论坛被垃圾信息刷爆了!!!
https://social.msdn.microsoft.com/Forums/zh-CN/caab1275-103e-470e-8888-ca39d1c48364/linehx2888?forum ...
- 这几天在搞UNITY3D,感觉回到了AS2
这几天在搞UNITY3D,感觉回到了AS2 代码没有MAIN, 代码在屏幕上,和元件绑定
- C# Interlocked 笔记
无锁代码下,在读写字段时使用内存屏障往往是不够的.在 64 位字段上进行加.减操作需要使用Interlocked工具类这样更加重型的方式.Interlocked也提供了Exchange和Compare ...
- LinkedList链式集合
LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.LinkedList的构造函数如下1. public LinkedList(): ——生成空的链表2. publ ...
- 借助91助手,将ibook中的pdf文件拷贝至其它的pdf阅读器中(ios设备无需越狱)
有时候在使用ios自带的ibook阅读pdf文件的时候,会发现ibook有些功能并不是那么方便.最近我就遇到了一例,我想在ibook中放一本比较大的pdf书,页数有几百吧,pdf文件本身每一章节都是有 ...
- AAL模版 中英文对照
来源:http://52brain.com/thread-17336-1-1.html Brodmann分区是一个根据细胞结构将大脑皮层划分为一系列解剖区域的系统.神经解剖学中所谓细胞结构(Cytoa ...
- K8 系统中省市县数据表的设计可以反映出什么? 通过一个基础业务表的设计品味软件系统的整体架构
1:没有严谨的Id思想,不变化的Id思想,看不见的Id的思想. 2:数据不严谨,没有上下级关系,没有树形结构,ParentId 的思想. 3:表之间的关系都是弱关联,基础数据一修改业务数据就容易乱套. ...
- AI: Jarvis
AI: Jarvis 扎克伯格本周二在facebook发布了一篇文章,介绍自己利用个人时间开发的一套在自己家里使用的AI系统,并将它命名为Jarvis,对!就是电影钢铁侠里的AI助手Jarvis. ...