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行给出询问: 询问形如 ...
随机推荐
- win7安装virtualbox遇到的问题
今天用台式机的时候想装个virtualbox跑centos做测试用,结果centos始终装不上,vbox一直提示无法开启任务.重装vbox,以及手动点击安装xxx.inf文件,都不行. 以前用的win ...
- mybatis底层源码分析之--配置文件读取和解析
现在企业级开发中ssm是很常见的技术标配,mybatis比hibernate轻量了很多,而且学习成本相对较低,简单易上手. 那么,问题来了,简单好用的mybatis底层到底是如何实现的呢?都使用了什么 ...
- Socket请求和Http请求的各自特点、区别及适用场景
Socket实现服务器与客户端之间的物理连接,并进行数据传输.主要有TCP/UDP两个协议.Socket处于网络协议的传输层.TCP:传输控制协议,面向连接的的协议,稳定可靠.当客户和服务器彼此交换数 ...
- 利用脚本获取mysql的tps,qps等状态信息
#!/bin/bash mysqladmin -uroot -p'123456' extended-status -i1|awk 'BEGIN{local_switch=0;print "Q ...
- JS中构造函数与函数
//构造函数中,如果返回的是一个对 象,那么就保留原意. 如果返回的是非对象,比如数字.布尔和字符串,那么就返回 this,如果没有 return 语句,那么也返回this. var myFun1 = ...
- pod install出现[!] /bin/bash -c错误,Installing Realm报错
pod install出现错误,具体错误信息如下: Installing Realm () [!] /bin/bash -c set -e sh build.sh cocoapods-setup co ...
- Preconditions优雅的检验参数
Preconditions里面的方法: 1 .checkArgument(boolean) : 功能描述:检查boolean是否为真. 用作方法中检查参数 失败时抛出的异常类型: IllegalArg ...
- Clob类型转化String类型
Clob clob=rs.getClob(列数); Clob clob=rs.getClob("列名");String content=clob.getSubString((lon ...
- math方法
1.丢弃小数部分,保留整数部分parseInt(5/2) 2.向上取整,有小数就整数部分加1 Math.ceil(5/2) 3,四舍五入. Math.round(5/2) 4,向下取整 Math.fl ...
- enbale blakboxing
chrome://flags/#enable-devtools-experiments