P2634 [国家集训队]聪聪可可(树上启发式合并)

题意:

一颗n个点的树,问其中两点之间的边上数的和加起来是3的倍数的点对有多少个?
输出这样的点对所占比例

题解:

没有修改,统计边长为3的倍数,经典的树上路径统计,树上启发式请求一战
但是调了一阵子没调出来,我对dsu的理解还是不够深,

代码:

待修改代码

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{#ifdef LOCALstartTime= clock();freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{#ifdef LOCALendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn= 1e5 + 9;
vector<PII> vec[maxn];
int sz[maxn];
int dis[maxn];
int son[maxn];
int Son;
int num[3];
int ans= 0;
void dfs_son(int u, int fa)
{sz[u]= 1;for (auto it : vec[u]) {int v= it.first;int w= it.second;if (v == fa)continue;dis[u]= dis[fa] + w;dfs_son(v, u);sz[u]+= sz[v];if (sz[v] > sz[son[u]])son[u]= v;}
}
void cal(int u, int fa, int LCA)
{int x= ((dis[LCA] - dis[u]) % 3 + 3) % 3;ans+= num[x];for (auto it : vec[u]) {int v= it.first;if (v != fa && v != son[u])cal(v, u, LCA);}
}
void add(int u, int fa, int val, int LCA)
{int Dis= (dis[u] - dis[LCA]) % 3;num[Dis]+= val;for (auto it : vec[u]) {int v= it.first;if (v != fa && v != son[u])add(v, u, val, LCA);}
}
void work(int u, int fa, int keep)
{for (auto it : vec[u]) {int v= it.first;if (v != fa && v != son[u])work(v, u, 0);}if (son[u]) {work(son[u], u, 1);Son= son[u];}add(u, fa, 1, u);Son= 0;cal(u, fa, u);if (!keep) {add(u, fa, -1, u);}
}
int main()
{//rd_test();int n;read(n);for (int i= 1; i < n; i++) {int u, v, w;read(u, v, w);vec[u].push_back({v, w});vec[v].push_back({u, w});}dis[1]= 1;dfs_son(1, 0);work(1, 0, 1);ll a= ans + n;ll b= 1ll * n * n;ll g= __gcd(a, b);printf("%lld/%lld\n", a / g, b / g);//Time_test();
}

洛谷上的AC代码:

#include <bits/stdc++.h>
using namespace std;
#define For(pos) for (int k= First[pos]; k; k= Next[k])
const int Maxn= 2e4 + 5;
int n, First[Maxn], to[Maxn * 2], Next[Maxn * 2], W[Maxn * 2], cnt;
int son[Maxn], size[Maxn], deep[Maxn];
inline void add(int z, int y, int w)
{Next[++cnt]= First[z];First[z]= cnt;to[cnt]= y;W[cnt]= w;
}
int ans= 0, P;
inline int R()
{char c;int sign= 1, res= 0;while ((c= getchar()) > '9' || c < '0')if (c == '-')sign= -1;res+= c - '0';while ((c= getchar()) >= '0' && c <= '9')res= res * 10 + c - '0';return res * sign;
}
void deal(int pos, int father)
{size[pos]= 1;For(pos){if (to[k] == father)continue;deep[to[k]]= deep[pos] + W[k];deal(to[k], pos);size[pos]+= size[to[k]];if (size[son[pos]] < size[to[k]])son[pos]= to[k];}
}
int q[4];inline void cal(int pos, int LCA)
{int x= (2 * deep[LCA] - deep[pos]) % 3 + 3;x= x % 3;ans+= q[x];
}
void work(int pos, int father, bool ca, int LCA)
{if (ca)cal(pos, LCA);elseq[deep[pos] % 3]++;For(pos){if (to[k] == father)continue;work(to[k], pos, ca, LCA);}
}
void dfs(int pos, int father, bool heavy)
{For(pos) if (to[k] != father && to[k] != son[pos]){dfs(to[k], pos, 0);}if (son[pos])dfs(son[pos], pos, 1);For(pos){if (to[k] == father || to[k] == son[pos])continue;work(to[k], pos, 1, pos);work(to[k], pos, 0, pos);}cal(pos, pos);q[deep[pos] % 3]++;if (!heavy)q[0]= q[1]= q[2]= 0;
}
int main()
{n= R();int a, b, w;for (int i= 1; i < n; i++) {a= R();b= R();w= R();add(a, b, w);add(b, a, w);}deal(1, 0);dfs(1, 0, 1);ans= ans * 2 + n;int di= n * n;for (int i= 2; i <= ans; i++)while (ans % i == 0 && di % i == 0) {ans/= i;di/= i;}if (ans == di)puts("1/1");elseprintf("%d/%d\n", ans, di);
}

P2634 [国家集训队]聪聪可可(树上启发式合并)相关推荐

  1. P2634 [国家集训队]聪聪可可(点分治做法)

    P2634 [国家集训队]聪聪可可 题意: 一颗n个点的树,问其中两点之间的边上数的和加起来是3的倍数的点对有多少个? 输出这样的点对所占比例 题解: 因为是求三的倍数,我们num来记录%3=0,1, ...

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

    luogu P2634 [国家集训队]聪聪可可 点分治 没啥难度,只需将路径取模,开桶,统计 d[0],d[1],d[2] 的值即可. ans = d[1]*d[2]*d[2]+d[0]*d[0] C ...

  3. 树上启发式合并问题 ---- 2019icpc南昌 K. Tree (树上启发式合并 + 动态开点线段树)

    题目链接 题目大意: 就是给你一颗树,每个点有个权值viv_ivi​,问你有多少对(x,y)(x,y)(x,y)满足: xxx不是yyy的祖先 yyy也不是xxx的祖先 xxx和yyy的距离不超过kk ...

  4. 树上启发式合并问题 ---- D. Tree and Queries[树上启发式合并+树状数组]

    题目链接 题目大意: 就是给你一棵树,树上每个节点都有一个颜色,在你mmm次询问每次询问给你一个节点uuu和一个数字kkk,问你在uuu这颗子树里面又少种颜色的结点个数是大于kkk; 解题思路: 看到 ...

  5. 树上启发式合并问题 ---- D. Tree Requests [状态压缩+树上启发式合并]

    题目链接 题目大意: 就是给你一颗树,树上每个点都有一个小写字母,现在给你m∈[1,5e5]m\in [1,5e5]m∈[1,5e5]次询问,每次询问给你一个u,和deep,问你在u这课子树中,距离1 ...

  6. 树上启动式合并问题 ---- D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [状态压缩+树上启发式合并]

    题目链接 题目大意: 一棵根为1 的树,每条边上有一个字符(a−va−va−v共22种). 一条简单路径被称为Dokhtar−kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树 ...

  7. 2019 ICPC 南昌 K. Tree(树上启发式合并,平衡树 treap)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://nanti.jisuanke.com/t/42586 Problem 给定一 ...

  8. 【学习笔记】树上启发式合并

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 树上启发式合并 模板 复杂度分析 例题 **Problem A. Arpa's letter-m ...

  9. (树上启发式合并)CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/CF741D Pro ...

最新文章

  1. Python轻松爬取Rosimm写真网站全部图片
  2. 为什么升级不了android版本,为啥你的手机无法升级到安卓7.0?原因都在这里!...
  3. [case12]演进式架构
  4. python导出csv不带引号的句子_python csv writer在不需要时添加引号
  5. 今日SGU 5.25
  6. Arduino可穿戴教程Linux平台下安装Arduino IDE
  7. python变量需要声明吗_python中可以声明变量类型吗
  8. 关闭Bootstrap的modal后,重新打开还会有input里上传的file解决
  9. 大神程序员都懂英文翻译,而你却因英语不行遭拒?
  10. vue 集成 sweetalert2 前端校验
  11. Python | 多种编码文件(中文)乱码问题解决
  12. linux ssh非交互脚本,Linux expect非交互式执行脚本
  13. lwip netbuf
  14. 安装Mycat 曾经踩的那些坑
  15. Tracup|工作时节省时间的三个奇异但是有用的小妙招
  16. 科普向-----验证码
  17. poj1606 Jugs(BFS)
  18. 常见Web服务器简介
  19. 前端绝对路径不显示图片_img标签使用绝对路径无法显示图片
  20. su - xxx Could not create session 无法su切换用户

热门文章

  1. 化学到底有多难难难难!为了让学生搞懂化学,竟然...
  2. 仅凭借一本薄薄的时间简史,征服了全球读者...
  3. 为什么软件工程师找不到工作?我想分享四个“恐怖故事”
  4. 2020下半年新机最新消息_提前剧透 2020 年下半年五大新机
  5. mysql in优化_MySQL 探秘: 1 整体架构
  6. php ip处理函数,PHP取ip地址函数
  7. python训练词库_在Python中训练NGramModel
  8. 我丢,去面试初级Java开发岗位,被问到泛型?
  9. redis下载+php,php+redis实现消息队列
  10. dhcp服务器显示主机名,linux – 当我没有在dhclient.conf中定义一个时,我的DHCP服务器如何知道我的机器的主机名?...