Codechef-ANCESTOR(树套树/CDQ分治)

题意:

给定两棵有根树,各有 N 个点。两棵树上的点分别被从 1 到 N 标号。两棵树的根均为标号为 1 的节点。

你的任务非常简单:对于每个 i,找到一个 j(j != i),使得在两棵树中 j 都是 i 的祖先。

输入数据第一行包含一个整数 T,表示数据组数。

每组数据第一行包含一个整数 N 表示每棵树中节点的个数。

接下来的 N - 1 行,每行包含两个整数 ui 和 vi,表示在第一棵树中有一条边连接 ui 和 vi。

再接下来的 N - 1 行,每行包含两个整数 ui 和 vi,表示在第二棵树中有一条边连接 ui 和 vi。

对于每组数据,输出一行包含 N 个整数,其中第 i 个整数为一个在两棵树中都是节点 i的祖先的节点标号。若不存在这样的节点标号,输出 0。

1 <= T <= 1e4, 2 <= N <= 5e5,各组数组N的总和不超过5e5, 1 <= ui, vi <= N。

分析:

对于两棵树求dfs序,那么每个节点掌管的子树就是一个连续的区间

对于两个树中的相同编号的点,能掌管的区间就可以用二维平面上的一个矩形来表示

那么对于每个询问,就是相当于求一个平面上一个点被多少个矩形所覆盖

可以用cdq分治/树套树来解决

对于树套树的话,此题对于每个线段树底下没必要动态开点再建线段树,只需要把第二维的区间左右端点保存到一个vector里就行了

对vector排序

查询的时候就相当于对每个vector里找一个点被覆盖了几次

时间复杂度O(nlog^2n)

转载于:https://www.cnblogs.com/wmrv587/p/7056563.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值