题目链接: Blood Cousins

大致题意

给出一片森林, 询问对于给定的点而言, 其k级祖先中有多少个点的深度和当前节点相同.

解题思路

dsu on tree

对于每个询问x, k而言, 我们假设x的k级祖先为p, 则对于每一个p, 我们求出其子树中不同深度的节点数量即可. 我们可以通过dsu on tree做法求出.

关于节点的k级祖先求法, 大家可以看这篇博客 ➡️ 博客链接

AC代码

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E5 + 10;
vector<int> edge[N];int son[N], sz[N];
int depth[N], f[N][18];
void dfs1(int x, int fa) {depth[x] = depth[fa] + 1;sz[x] = 1;f[x][0] = fa;rep(i, 17) f[x][i] = f[f[x][i - 1]][i - 1];for (auto& to : edge[x]) {if (to == fa) continue;dfs1(to, x);sz[x] += sz[to];if (sz[to] > sz[son[x]]) son[x] = to;}
}int getk(int x, int k) {if (!k) return x;int index = log2(k);return getk(f[x][index], k - (1 << index));
}vector<pair<int, int>> query[N]; // val, id
int res[N];
unordered_map<int, int> mp; // depth, cou;
void calc(int x, int fa, int pson) {mp[depth[x]]++;for (auto& to : edge[x]) {if (to == fa or to == pson) continue;calc(to, x, pson);}
}
void dfs2(int x, int fa, int tp) {for (auto& to : edge[x]) {if (to == fa or to == son[x]) continue;dfs2(to, x, 0);}if (son[x]) dfs2(son[x], x, 1);calc(x, fa, son[x]);for (auto& [val, id] : query[x]) res[id] = mp[val] - 1;if (!tp) mp.clear();
}
int main()
{int n; cin >> n;rep(i, n) {int p; scanf("%d", &p);edge[p].push_back(i);}for (auto& op : edge[0]) dfs1(op, 0);int m; cin >> m;rep(i, m) {int x, k; scanf("%d %d", &x, &k);int p = getk(x, k);query[p].push_back({ k + depth[p], i }); //采用相对于根节点的深度.}for (auto& op : edge[0]) dfs2(op, 0, 0); //由于是森林, 所以根节点应为轻儿子, 否则WA9rep(i, m) printf("%d%c", res[i], " \n"[i == m]);return 0;
}

END

Blood Cousins (dsu on tree + 求第k级祖先)相关推荐

  1. 【luogu P5903】【模板】树上 k 级祖先(长链剖分)

    [模板]树上 k 级祖先 题目链接:luogu P5903 题目大意 给你一棵树,要你在线 O(1) 求一个点的 k 级祖先. 思路 这个我们可以用长链剖分来做,从而可以做到预处理 O ( n log ...

  2. CF 246E. Blood Cousins Return [dsu on tree STL]

    题意: 一个森林,求k级后代中多少种不同的权值 用set维护每个深度出现的权值 一开始一直在想删除怎么办,后来发现因为当前全局维护的东西里都是当前子树里的,如果要删除那么当前一定是轻儿子,直接清空se ...

  3. dsu on tree 题集 + ac代码

    文章目录 **入门讲解** **[600E - Lomsat gelral](https://codeforces.ml/problemset/problem/600/E)** **[树上数颜色](h ...

  4. 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    [题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...

  5. 二叉树的堂兄弟 Cousins in Binary Tree

    文章目录 二叉树的堂兄弟 Cousins in Binary Tree 思路 Tag 二叉树的堂兄弟 Cousins in Binary Tree 在二叉树中,根节点位于深度 0 处,每个深度为 k ...

  6. 2020 China Collegiate Programming Contest Changchun F - Strange Memory(dsu on tree + 位运算小技巧)

    题目连接: https://codeforces.com/gym/102832/problem/F 首先写这个题的时候要注意内存的问题 不要瞎几把define int long long 题解: 考虑 ...

  7. CF375D Tree and Queries(dsu on tree)

    题解: 个人感觉这个题目是一个挺不错的题的.(这里就不说dsu on tree的这个过程是什么了) 我们在dsu on tree计算答案时需要有一个小小技巧去优化一下时间复杂度. 就是当我们用一个cn ...

  8. 【UOJ#388】【UNR#3】配对树(线段树,dsu on tree)

    [UOJ#388][UNR#3]配对树(线段树,dsu on tree) 题面 UOJ 题解 考虑一个固定区间怎么计算答案,把这些点搞下来建树,然后\(dp\),不难发现一个点如果子树内能够匹配的话就 ...

  9. [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree

    题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...

最新文章

  1. 互联网或将进入泡沫2.0时代
  2. 008_Maven Eclipse
  3. 【Spring注解系列05】@Import注入原理
  4. 我的世界局域网联机找不到服务器,我的世界局域网联机显示无效的会话和搜不到主机...
  5. JAVA子类和父类在同一个包中,子类和父类在同一个包中继承性
  6. LFS-构建自己的linux
  7. Angular问题02 创建模块失败、 angular-cli名称问题、升级angular-cli
  8. 我的树莓派3配置脚本
  9. hdu 3746 kmp求循环节
  10. 网易通行证html代码,JavaScript实现仿网易通行证表单验证
  11. 易语言64位进程注入DLL
  12. Openwrt使用指定版本的toolchain工具链
  13. 经典古诗文与人工智能创作诗歌 之诗三百(AI)
  14. 解决Jar包双击打不开!
  15. 短信通知接口json报文开发设计总结
  16. ArcGIS教程:基于ArcGIS的CAD数据向GIS数据转换方法
  17. 高校手机签到系统——Ksoap2的一些使用心得(补充)
  18. echarts 双Y轴,双X轴, 折线图折点,折点与直方对应
  19. sun服务器多磁盘配置信息,配置 Solaris iSCSI initiator
  20. JAVA泛型实例化代码

热门文章

  1. 美多商城之商品(2)
  2. 残差/shortcur/Resnet 究竟好在哪里
  3. 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构
  4. c语言编程上升沿怎样写,plc结构化编程怎么写
  5. Nacos学习之初识Nacos
  6. VMware安装红旗Linux
  7. Docker 常见使用
  8. 宅家羊毛党是怎么做到月入上万的
  9. 谷云科技通过CMMI3认证,研发实力受国际权威认可!
  10. java全角空格转换半角空格