CodeForces 570D - Tree Requests - [DFS序+二分]
题目链接:https://codeforces.com/problemset/problem/570/D
题解:
这种题,基本上容易想到DFS序。
然后,我们如果再把所有节点分层存下来,那么显然可以根据 $in[v],out[v]$ 在层内二分出一段属于 $v$ 的子树的节点。
那么我们进一步考虑,如果把一层的节点,按 $a \sim z$ 再分开来,用一个 $S[c][d]$ 数组来存所有字母为 $c$,深度为 $d$ 的节点的 $in[]$ 值。
这样一来,对于一个询问 $v,h$,就在 $S[c][h]$ 二分找到属于区间 $[in[v],out[v]]$ 的那一段,这一段的长度如果为 $r$,说明 $v$ 节点的子树中、深度为 $h$ 的、字母为 $c$ 的节点有 $r$ 个,
这个 $r$ 若为偶数,那么必然可以用来组成回文串;如果为奇数,那么最多只能一个字母的个数是奇数,否则就不能组成回文串了。
AC代码:
#include<bits/stdc++.h>
#define pb(x) push_back(x)
using namespace std;
typedef pair<int,int> P;
#define fi first
#define se second
const int maxn=5e5+; int n,m;
char c[maxn];
int d[maxn];
vector<int> G[maxn];
vector<int> S[][maxn]; int clk;
int maxd;
int in[maxn],out[maxn];
void dfs(int x,int depth)
{
in[x]=++clk;
maxd=max(maxd,depth);
S[c[x]-'a'][d[x]=depth].pb(in[x]);
for(auto y:G[x]) dfs(y,depth+);
out[x]=clk;
} int main()
{
scanf("%d%d",&n,&m);
for(int y=,x;y<=n;y++)
{
scanf("%d",&x);
G[x].pb(y);
}
scanf("%s",c+); clk=, maxd=, dfs(,); while(m--)
{
int v,h; scanf("%d%d",&v,&h);
if(d[v]>=h)
{
printf("Yes\n");
continue;
} int cnt=;
for(int i=;i<;i++)
{
int L=lower_bound(S[i][h].begin(),S[i][h].end(),in[v])-S[i][h].begin();
int R=upper_bound(S[i][h].begin(),S[i][h].end(),out[v])-S[i][h].begin();
cnt+=(R-L)%;
}
if(cnt>) printf("No\n");
else printf("Yes\n");
}
}
CodeForces 570D - Tree Requests - [DFS序+二分]的更多相关文章
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
- Codeforces 570D - Tree Requests(树上启发式合并)
570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 ...
- Codeforces Round #316 (Div. 2) D. Tree Requests dfs序
D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces 570D - Tree Requests【树形转线性,前缀和】
http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和 ...
- codeforces 570D.Tree Requests
[题目大意]: 给定一棵树,树的每个节点对应一个小写字母字符,有m个询问,每次询问以vi为根节点的子树中,深度为hi的所有节点对应的字符能否组成一个回文串: [题目分析]: 先画个图,可看出每次询问的 ...
- codeforces 570 D. Tree Requests (dfs)
题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- Codeforces 620E New Year Tree(DFS序 + 线段树)
题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...
随机推荐
- Unity应用架构设计(9)——构建统一的 Repository
谈到 『Repository』 仓储模式,第一映像就是封装了对数据的访问和持久化.Repository 模式的理念核心是定义了一个规范,即接口『Interface』,在这个规范里面定义了访问以及持久化 ...
- celery --分布式任务队列
一.介绍 celery是一个基于python开发的分布式异步消息任务队列,用于处理大量消息,同时为操作提供维护此类系统所需的工具. 它是一个任务队列,专注于实时处理,同时还支持任务调度.如果你的业务场 ...
- php生成毫秒时间戳的例子
php时间函数time()生成当前时间的秒数,但是在一些情况下我们需要获取当前服务器时间和GMT(格林威治时间)1970年1月0时0分0秒的毫秒数,与Java中的currentTimeMilis()函 ...
- Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息
Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息 1.1. 异常的处理模式exit continue undo模式 1 1.2. 捕获所有异常使用 DECLARE ...
- SpringMvc的Url映射和传参案例(转)
Springmvc的基本使用,包括url映射.参数映射.页面跳转.ajax和文件上传 以前学习的时候写的代码案例,今天整理笔记的时候找到了,很久没有来园子了,发上来当个在线笔记用吧,免的时间长了又忘了 ...
- WEB API Filter的使用以及执行顺序
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...
- 修改maven镜像为阿里云,速度快
http://www.cnblogs.com/panxuejun/p/6140768.html修改maven根目录下的conf文件夹中的setting.xml文件,(或者当前用户目录 的 .m2 目录 ...
- 会使用基本的Render函数后,就会想,这怎么用 v-for/v-if/v-model;我写个vue Render函数进阶
https://blog.csdn.net/wngzhem/article/details/54291024
- 导出jqgrid表格数据为EXCEL文件,通过tableExport.js插件。
今天公司项目需要做个导出功能,将jqgrid查询出的数据导出为EXCEL表格文件,期间遇到两个问题: 1.导出报错 uncaught exception: INVALID_CHARACTER_ERR: ...
- 基于【CentOS-7+ Ambari 2.7.0 + HDP 3.0】搭建HAWQ数据仓库01 —— 准备环境,搭建本地仓库,安装ambari
一.集群软硬件环境准备: 操作系统: centos 7 x86_64.1804 Ambari版本:2.7.0 HDP版本:3.0.0 HAWQ版本:2.3.05台PC作为工作站: ep-bd01 e ...