Codeforces Round #316 (Div. 2) D. Tree Requests dfs序
2 seconds
256 megabytes
standard input
standard output
Roman planted a tree consisting of n vertices. Each vertex contains a lowercase English letter. Vertex 1 is the root of the tree, each of the n - 1 remaining vertices has a parent in the tree. Vertex is connected with its parent by an edge. The parent of vertex i is vertex pi, the parent index is always less than the index of the vertex (i.e., pi < i).
The depth of the vertex is the number of nodes on the path from the root to v along the edges. In particular, the depth of the root is equal to 1.
We say that vertex u is in the subtree of vertex v, if we can get from u to v, moving from the vertex to the parent. In particular, vertex v is in its subtree.
Roma gives you m queries, the i-th of which consists of two numbers vi, hi. Let's consider the vertices in the subtree vi located at depthhi. Determine whether you can use the letters written at these vertices to make a string that is a palindrome. The letters that are written in the vertexes, can be rearranged in any order to make a palindrome, but all letters should be used.
The first line contains two integers n, m (1 ≤ n, m ≤ 500 000) — the number of nodes in the tree and queries, respectively.
The following line contains n - 1 integers p2, p3, ..., pn — the parents of vertices from the second to the n-th (1 ≤ pi < i).
The next line contains n lowercase English letters, the i-th of these letters is written on vertex i.
Next m lines describe the queries, the i-th line contains two numbers vi, hi (1 ≤ vi, hi ≤ n) — the vertex and the depth that appear in thei-th query.
Print m lines. In the i-th line print "Yes" (without the quotes), if in the i-th query you can make a palindrome from the letters written on the vertices, otherwise print "No" (without the quotes).
6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2
Yes
No
Yes
Yes
Yes
String s is a palindrome if reads the same from left to right and from right to left. In particular, an empty string is a palindrome.
Clarification for the sample test.
In the first query there exists only a vertex 1 satisfying all the conditions, we can form a palindrome "z".
In the second query vertices 5 and 6 satisfy condititions, they contain letters "с" and "d" respectively. It is impossible to form a palindrome of them.
In the third query there exist no vertices at depth 1 and in subtree of 4. We may form an empty palindrome.
In the fourth query there exist no vertices in subtree of 6 at depth 1. We may form an empty palindrome.
In the fifth query there vertices 2, 3 and 4 satisfying all conditions above, they contain letters "a", "c" and "c". We may form a palindrome "cac".
题意:给你一棵树,n个节点,m个询问;根节点为1;根结点的深度为1,
每个节点含有一个权值;
询问给你一个节点node,以node为根的子树中深度为x的结点,能否形成回文串;
思路:首先,能行成回文,只需要奇数的字母个数<=1;状态压缩标记即可;
然后处理这课树,dfs序形成一个序列处理;
对于m个询问, 两种思路:
1:打表每个字母+深度进行存in[i](vector),然后m个询问复杂度o(26*(m*log(n));
2:可以再广搜一遍,对于深度相同的必然是连续的一段序列,利用前缀异或和处理,复杂度(m*log(n));
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=5e5+,M=1e6+,inf=1e9+;
const ll INF=1e18+,mod=;
int in[N],out[N],tot,a[N],flag[N],deep[N];
struct is
{
int v,nex;
}edge[N<<];
int head[N<<],edg;
int n,p;
void init()
{
memset(head,-,sizeof(head));
memset(a,,sizeof(a));
edg=;
tot=;
}
void add(int u,int v)
{
edg++;
edge[edg].v=v;
edge[edg].nex=head[u];
head[u]=edg;
}
void dfs(int u,int fa,int d)
{
deep[u]=d;
in[u]=++tot;
for(int i=head[u];i!=-;i=edge[i].nex)
{
int v=edge[i].v;
if(v==fa)continue;
dfs(v,u,d+);
}
out[u]=tot;
}
char ch[N];
int root,x;
vector<int>ans[][N];
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
init();
for(int i=;i<=n;i++)
{
int v;
scanf("%d",&v);
add(i,v);
add(v,i);
}
dfs(,-,);
scanf("%s",ch+);
//for(int i=1;i<=n;i++)
// cout<<in[i]<<" "<<out[i]<<endl;
for(int i=;i<=n;i++)
flag[in[i]]=i;
for(int i=;i<=n;i++)
a[i]=deep[flag[i]];
for(int i=;i<=n;i++)
ans[ch[flag[i]]-'a'][a[i]].push_back(in[flag[i]]);
for(int i=;i<;i++)
{
for(int j=;j<=n;j++)
{
sort(ans[i][j].begin(),ans[i][j].end());
}
}
/*for(int i=0;i<26;i++)
{
for(int j=1;j<=n;j++)
{
cout<<j<<" ";
for(int k=0;k<ans[i][j].size();k++)
cout<<ans[i][j][k]<<" ";
cout<<endl;
}
cout<<"~~~~"<<endl;
}*/
while(q--)
{
scanf("%d%d",&root,&x);
if(deep[root]>=x)
{
printf("Yes\n");
continue;
}
int tot=;
for(int i=;i<;i++)
{
int pos1=lower_bound(ans[i][x].begin(),ans[i][x].end(),in[root])-ans[i][x].begin()-;
int pos2=upper_bound(ans[i][x].begin(),ans[i][x].end(),out[root])-ans[i][x].begin()-;
//cout<<pos1<<" "<<pos2<<endl;
tot+=(pos2-pos1)%;
}
if(tot>=)
printf("No\n");
else
printf("Yes\n");
}
}
return ;
}
Codeforces Round #316 (Div. 2) D. Tree Requests dfs序的更多相关文章
- Codeforces Round #316 (Div. 2) D Tree Requests
官方题解是离线询问,dfs树形转线性,然后二分找区间. 还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案. 代码是学 ...
- Codeforces Round #316 (Div. 2) D. Tree Requests(dsu)
题目链接 题意:对于m次询问 求解以vi为根节点 深度为hi的的字母能不能组合成回文串. 思路:暴力dsu找一边 简直就是神技! #include<bits/stdc++.h> #defi ...
- Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)
https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...
- Codeforces Round #646 (Div. 2) E. Tree Shuffling dfs
题意: 给你n个节点,这n个节点构成了一颗以1为树根的树.每一个节点有一个初始值bi,从任意节点 i 的子树中选择任意k个节点,并按他的意愿随机排列这些节点中的数字,从而产生k⋅ai 的成本.对于一个 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces Round #316 (Div. 2)
A. Elections time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- Codeforces Round #268 (Div. 1) 468D Tree(杜教题+树的重心+线段树+set)
题目大意 给出一棵树,边上有权值,要求给出一个1到n的排列p,使得sigma d(i, pi)最大,且p的字典序尽量小. d(u, v)为树上两点u和v的距离 题解:一开始没看出来p需要每个数都不同, ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
随机推荐
- apache查看工作模式及调优
一,查看工作模式 /usr/sbin/httpd -l Compiled in modules: core.c prefork.c http_core.c mod_so.c 如果出现prefo ...
- js串讲回顾
注:1.xx.nextSibling.css.xxx->xx的下一个元素的css样式;2. window.opener.document.getElementById("cms&quo ...
- MVC控制器取参数值
1.这个方法是获取提交表单里的参数值,也就是有name="xxx"的属性的表单控件的值 FormCollection传值 public ActionResult Login(For ...
- 安卓仿微信Tab页用Fragment实现
最终效果图如: 实现步骤: 新建项目tabdemo,我选的是4.0.3版本,然后依次新建三个Fragment,名字分别为:ChatFragment.FriendFragment.FindFragmen ...
- 针对ajax执行后swiper特效无法执行解决方案
ajax执行后重新绑定swiper事件.
- angularJs自定义指令.directive==类似自定义标签
创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名 ...
- 加载UI
weak情况 1 2 3 4 @property (weak,nonatomic) UILabel *nameLabel; UILabel *nameLabel = [[UILabel alloc ...
- Python学习【第一篇】Python简介
Python简介 Python前世今生 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 现在,全世界差不多有600多种编 ...
- iOS: 上传App到AppStore,由于Xcode上传太慢,换成Application Loader上传,速度秒传
一.遇到的遭遇 在之前的项目开发中,本人有点固执,一直采用xcode打包后再上传,结果可想而知: (1)要么上传时速度慢的跟蜗牛似的,等的我心力交瘁(不排除网络不给力的原因,公司这个吊问题快把我气疯了 ...
- SQLServer性能调优3之索引(Index)的维护
前言 前一篇的文章介绍了通过建立索引来提高数据库的查询性能,这其实只是个开始.后续如果缺少适当的维护,你先前建立的索引甚至会成为拖累,成为数据库性能的下降的帮凶. 查找碎片 消除碎片可能是索引维护最常 ...