G. Unusual Entertainment

原题链接:https://codeforces.com/contest/1899/problem/G

题目大意:

给定一棵树,根节点为1,给定一个\(1\) ~ \(n\) 的排列 \(p\) ,\(q\) 次查询,每次给出 \(l\) 和 \(r\) 还有 \(x\),查询序列 \(p\) 的 \(l\) ~ \(r\) 范围内是否存在节点编号 \(y\) 为 \(x\) 的子孙节点,如果有则输出 \(YES\),否则输出 \(NO\)。

思路:

解法一(官方题解做法):

\(x\) 的子孙节点 \(y\) 在 \(dfs\) 时,入栈时间 \(tin[y]\) 出栈时间 \(tout[y]\),满足:\(tin[x] < tin[y]\) \(tout[x] >= tout[y]\),每次查询序列\(p\) 的 \(l\) ~ \(r\) 中是否存在 \(x\) 的子孙节点就转化为查询序列 \(p\) 的 \(l\) ~ \(r\) 中对应的 \(y = p[i], l <= i <= r\),是否有 \(tin[x] < tin[y]\) and \(tout[x] >= tout[y]\)。构建序列\(a\) 且 \(a[i] = tin[p[i]]\),那么原问题就转化为在序列\(a\) 的 \(l\) ~ \(r\) 中对应的 \(tin[x] <= a[i] <= tout[x]\) 个数的查询。然后就可以维护一个线段树,这里的线段树相当于是一个存储过程的归并排序,每次查询相应区间上的个数。线段树的时空间复杂度均为 \(O(nlgn)\) ,每次通过二分查找即可确定个数。

总时间复杂度为:\(O(nlgn) + O(q*lg(n)^2)\) -> 二分的lg与线段树的lg相乘

解法二(树链剖分)

对整棵树进行树剖后,父节点 \(x\) 的子节点的序列一定在其之后的 \(id[x]+1\) 到 \(id[x]+sz[x]-1\) 之间,利用序列 \(p\) 我们可以得到对应节点编号 \(y\) 在其中的位置 \(py\),将其视为 \(nw[id[y]]\) 就可以利用这个信息去建立线段树,处理方式与方法一相同,也是查询个数,但查询的是 \(x\) 的子孙节点中位置信息在 \(l\) ~ \(r\)之间的个数。

代码:

方法一:

#include <bits/stdc++.h>
using namespace std; #define TII tuple<int, int, int>
#define all(x) x.begin(), x.end() typedef long long ll;
typedef pair<int, int> PII; const int N = 1e5 + 10, M = 2e5 + 10, K = 20, mod = 998244353;
const int INF = 0x3f3f3f3f;
const ll INF_L = 1e15; int n, m; vector<vector<int>> e;
int timestamp;
vector<int> tin, tout; struct Node{
int l, r;
vector<int> v;
}tr[4 * N]; inline void add(int a, int b){ e[a].push_back(b); } void dfs(int x, int father){
tin[x] = timestamp ++;
for(auto y : e[x]){
if(y == father) continue;
dfs(y, x);
}
tout[x] = timestamp;
} void build(int u, int l, int r, vector<int> &a){
tr[u].v.clear();
if(l == r) tr[u] = {l, r, {a[l]}};
else{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid, a), build(u << 1 | 1, mid + 1, r, a);
merge(all(tr[u << 1].v), all(tr[u << 1 | 1].v), back_inserter(tr[u].v));
}
} int count(int u, int l, int r, int low, int up){
if(tr[u].l >= l && tr[u].r <= r) return lower_bound(all(tr[u].v), up) - lower_bound(all(tr[u].v), low);
else{
int mid = tr[u].l + tr[u].r >> 1;
int res = 0;
if(l <= mid) res += count(u << 1, l, r, low, up);
if(r > mid) res += count(u << 1 | 1, l, r, low, up);
return res;
}
} void solve()
{
int q;
cin >> n >> q;
e.assign(n + 1, vector<int>());
for(int i = 1; i < n; i ++){
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
} timestamp = 0;
tin.resize(n + 1);
tout.resize(n + 1);
dfs(1, -1); vector<int> p(n + 1);
for(int i = 1; i <= n; i ++) cin >> p[i]; vector<int> a(n + 1);
for(int i = 1; i <= n; i ++) a[i] = tin[p[i]]; build(1, 1, n, a); while(q --){
int l, r, x;
cin >> l >> r >> x;
if(count(1, l, r, tin[x], tout[x])) cout << "Yes\n";
else cout << "No\n";
}
} int main()
{
cin.tie(0)->sync_with_stdio(false);
cout.tie(0); int t = 1;
cin >> t; while (t--) solve(); return 0;
}

方法二(待补)

妙妙线段树+DFS序判断子孙节点,但似乎还可以树链剖分?(CF Div3 909 G)的更多相关文章

  1. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  2. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  3. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  4. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  5. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  6. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  7. 瞎写的树dfs序

    这里枚举了树的DFS序来解决树上问题的多个板子,自己最好多看看. ↓改↓ ↓求↓ 点 点 ————————>>>这个就算了 点 树 简单, BIT 点 链 重点! 树 树 简单, 线 ...

  8. 51 nod 1681 公共祖先 (主席树+dfs序)

    1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...

  9. 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set

    [题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...

  10. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

随机推荐

  1. MybatisPlus - [08] RestFul

    编号 接口 请求方式 请求路径 请求参数 返回值 1 新增用户 POST /users 用户表单实体 无 2 删除用户 DELETE /users/{id} 用户id 无 3 根据id查询用户 GET ...

  2. win11 - 设置FTP服务详细教程

    题记部分 一.开启FTP服务 https://blog.csdn.net/qq_42142258/article/details/131725760 二.配置FTP服务 https://blog.cs ...

  3. MySQL Q&A - [02] windows上MySQL的安装路径变更之后无法启动MySQL服务

    参考:https://blog.csdn.net/weixin_45271005/article/details/130091868 Step1:首先,变更之前,需要保证MySQL服务是停止运行的 S ...

  4. Hi3516EV200 编译环境配置及交叉编译软件包

    基础信息 OS: Ubuntu 16.04 xenial SDK 版本: Hi3516EV200R001C01SPC012 - Hi3516EV200_SDK_V1.0.1.1 SDK 包路径:Hi3 ...

  5. 阿里云Windows server 2016服务器Antimalware Service Executable进程占比高,cpu接近100%,强制关闭该进程实测

    问题描述:阿里云Windows server 2016服务器Antimalware Service Executable进程占比高,cpu接近100%,需要强制关闭该进程,排查问题,进入系统服务关闭, ...

  6. linux服务问题传文件连不上问题远程问题等

    通过iptables相关命令实现防火墙的打开和关闭 1.首先可以在打开的终端使用iptables --help查看帮助使用命令: 2.查看防火墙状态:service iptables status(此 ...

  7. FastAPI 核心机制:分页参数的实现与最佳实践

    title: FastAPI 核心机制:分页参数的实现与最佳实践 date: 2025/3/13 updated: 2025/3/13 author: cmdragon excerpt: 在构建现代W ...

  8. ant design pro 使用 getFieldValue、setFieldsValue

    getFieldValue 获取表单指定 name 值,setFieldsValue 为表单指定 name 设定值 import type { ProFormInstance } from '@ant ...

  9. mysql 2003远程访问失败 mysql8配置远程访问

    # mysql -uroot -p #进入数据库 > use mysql;#进入数据库 > select host, user, authentication_string, plugin ...

  10. IvorySQL 4.0 之 Invisible Column 功能解析

    前言 随着数据库应用场景的多样化,用户对数据管理的灵活性和隐私性提出了更高要求.IvorySQL 作为一款基于 PostgreSQL 并兼容 Oracle 的开源数据库,始终致力于在功能上保持领先和创 ...