【P2634】聪聪可可——点分治
(题面来自Luogu)
题目描述
聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已经玩儿腻了这种低智商的游戏。
他们的爸爸快被他们的争吵烦死了,所以他发明了一个新游戏:由爸爸在纸上画n个“点”,并用n-1条“边”把这n个“点”恰好连通(其实这就是一棵树)。并且每条“边”上都有一个数。接下来由聪聪和可可分别随即选一个点(当然他们选点时是看不到这棵树的),如果两个点之间所有边上数的和加起来恰好是3的倍数,则判聪聪赢,否则可可赢。
聪聪非常爱思考问题,在每次游戏后都会仔细研究这棵树,希望知道对于这张图自己的获胜概率是多少。现请你帮忙求出这个值以验证聪聪的答案是否正确。
输入输出格式
输入格式:
输入的第1行包含1个正整数n。后面n-1行,每行3个整数x、y、w,表示x号点和y号点之间有一条边,上面的数是w。
输出格式:
以即约分数形式输出这个概率(即“a/b”的形式,其中a和b必须互质。如果概率为1,输出“1/1”)。
用点分治统计从每个点u出发的路径,在cnt[k]中计数;其中k属于{0, 1, 2},表示该数组统计通过当前节点的长度%3等于k的路径数目。考虑将这些节点两两组合成长度%3等于0的路径:cnt[1]可以与cnt[2]两两组合,且题中给定的是有序点对,那么通过点u的满足条件的路径数ret += (cnt[2] * cnt[1] * 2)。cnt[0]可以两两组合,且可以重复,则ret += cnt[0] * cnt[0]。
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cctype>
- #define BUG puts("$$$")
- #define maxn 20010
- using namespace std;
- const int inf = 0x3f3f3f3f;
- int n;
- template <typename T>
- void read(T &x) {
- x = 0;
- char ch = getchar();
- int f = 1;
- while (!isdigit(ch)) {
- if (ch == '-') f = -1;
- ch = getchar();
- }
- while (isdigit(ch)) {
- x = x * 10 + (ch ^ 48);
- ch = getchar();
- }
- x *= f;
- }
- long long gcd(long long a, long long b) {
- if (!b) return a;
- return gcd(b, a % b);
- }
- int head[maxn], top;
- struct E {
- int to, nxt, w;
- } edge[maxn << 1];
- inline void insert(int u, int v, int w) {
- edge[++top] = (E) {v, head[u], w};
- head[u] = top;
- }
- int cnt[3];
- int size[maxn], Size, mn, root;
- bool vis[maxn];
- void find_rt(int u, int pre) {
- size[u] = 1;
- int son = 0;
- for (int i = head[u]; i; i = edge[i].nxt) {
- int v = edge[i].to;
- if (v == pre || vis[v]) continue;
- find_rt(v, u);
- size[u] += size[v];
- if (size[v] > size[son]) son = v;
- }
- int cur = max(size[son], Size - size[u]);
- if (cur < mn)
- mn = cur, root = u;
- }
- void dfs(int u, int pre, int depth, int val) {
- cnt[depth % 3] += val;
- for (int i = head[u]; i; i = edge[i].nxt) {
- int v = edge[i].to;
- if (v == pre || vis[v]) continue;
- dfs(v, u, depth + edge[i].w, val);
- }
- }
- long long solve(int u, int extra) {
- dfs(u, 0, extra, 1);
- long long ret = 1LL * cnt[1] * cnt[2] * 2 + 1LL * cnt[0] * cnt[0];
- dfs(u, 0, extra, -1);
- return ret;
- }
- long long ans;
- void divide(int u) {
- vis[u] = true;
- ans += solve(u, 0);
- int curSize = Size;
- for (int i = head[u]; i; i = edge[i].nxt) {
- int v = edge[i].to;
- if (vis[v]) continue;
- ans -= solve(v, edge[i].w);
- mn = inf, Size = size[u] > size[v] ? size[v] : curSize - size[u];
- find_rt(v, u);
- divide(root);
- }
- }
- int main() {
- read(n);
- int u, v, w;
- for (int i = 1; i < n; ++i) {
- read(u), read(v), read(w);
- insert(u, v, w), insert(v, u, w);
- }
- mn = inf, Size = n;
- find_rt(1, 0);
- divide(root);
- long long down = 1LL * n * n, k = gcd(down, ans);
- printf("%lld/%lld", ans / k, down / k);
- return 0;
- }
【P2634】聪聪可可——点分治的更多相关文章
- [bzoj2152][聪聪和可可] (点分治+概率)
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
- bzoj2152 / P2634 [国家集训队]聪聪可可(点分治)
P2634 [国家集训队]聪聪可可 淀粉质点分治板子 边权直接 mod 3 直接点分治统计出所有的符合条件的点对再和总方案数约分 至于约分.....gcd搞搞就好辣 #include<iostr ...
- 洛谷 P2634 [国家集训队]聪聪可可-树分治(点分治,容斥版) +读入挂+手动O2优化吸点氧才过。。。-树上路径为3的倍数的路径数量
P2634 [国家集训队]聪聪可可 题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
- P2634 [国家集训队]聪聪可可(题解)(点分治)
P2634 [国家集训队]聪聪可可(题解)(点分治) 洛谷题目 #include<iostream> #include<cstdlib> #include<cstdio& ...
- 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)
洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...
- AC日记——【模板】点分治(聪聪可可) 洛谷 P2634
[模板]点分治(聪聪可可) 思路: 点分治: (感谢灯神) 代码: #include <bits/stdc++.h> using namespace std; #define maxn 2 ...
- 洛谷-P2634 [国家集训队]聪聪可可 点分治
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
- 洛谷P2634 [国家集训队]聪聪可可 (点分治)
题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...
- 洛谷 P2634 BZOJ 2152 【模板】点分治(聪聪可可)
题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...
随机推荐
- 正式班D16
2020.10.27星期二 正式班D16 目录 9.9 字符处理命令 9.9.1 sort排序 9.9.2 uniq去重 9.9.3 cut处理规律文本 9.9.4 tr替换 9.9.5 wc统计 9 ...
- 【转】Hello SDL: Your First Graphics Window
FROM: http://lazyfoo.net/tutorials/SDL/01_hello_SDL/index2.php Hello SDL: Your First Graphics Window ...
- Luogu P2536 [AHOI2005]病毒检测
题意 给一个有通配符的模式串和 \(n\) 个文本串,其中 ? 可以匹配任意字符,* 可以匹配 \(0\) 或任意多个字符,求 \(n\) 个文本串中无法与模式串匹配的数量. \(\texttt{Da ...
- 在充电桩联网部署方案中4G DTU的优势是什么
充电桩作为电动汽车充电生态链的一环,具有非常重要的作用,成都远向电子为电动车充电桩.充电站提供专业的无线通信组网产品与技术解决方案,协助充电桩厂家.充电桩运营商.商业充电服务商实现:充电桩设备工作状态 ...
- JMeter实战(三) 界面使用
JMeter 有 2 种运行方式,一种是 CLI,一种是 GUI,本篇文章就来介绍一下后者,图形用户界面,因为后续文章大部分都是基于 GUI 的. 本文演示的是英文版,想用中文的同学可以在菜单栏点击 ...
- 深入研究Paxos算法原理
一.Paxos算法产生的背景 Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一,其解决的问题就是在分布式系统中如何就某个值(决议)达成一致. ...
- 转载-Eclipse导入第三方库的方法
作者:wyf_phper 原文:https://blog.csdn.net/qq_32985981/article/details/49976193 一:导入*.jar包步骤:将下载好的jar包复制到 ...
- dubbo2.7.X版本带来的服务注册和服务调用方式改变
参考地址:https://www.cnblogs.com/alisystemsoftware/p/13064620.html 注册中心数据结构格式改变(service:接口服务,application ...
- Spring Boot API 统一返回格式封装
今天给大家带来的是Spring Boot API 统一返回格式封装,我们在做项目的时候API 接口返回是需要统一格式的,只有这样前端的同学才可对接口返回的数据做统一处理,也可以使前后端分离 模式的开发 ...
- C# 集合类(二)
C# 集合类自己经常用到: 数组(Array).动态数组(ArrayList).列表(List).哈希表(Hashtable).字典(Dictionary),对于经常使用的这些数据结构,做一个总结,便 ...