codeforces 570 D Tree Requests
题意:给出一棵树。每一个结点都有一个字母,有非常多次询问,每次询问。以结点v为根的子树中高度为h的后代是否可以经过调整变成一个回文串。
做法:
推断能否够构成一个回文串的话,仅仅须要知道是否有大于一个的奇数数目的字母就可以。为了非常快的訪问到一个区间。记录前缀和就可以。为了省内存,状压奇偶就可以。
为了非常快的找到以结点v为根的子树中高度为h的后代,须要dfs整棵树。然后记录每一个结点第一次訪问它的时间戳以及离开它的时间戳,就能够二分出来。
为了省内存,能够离线处理询问。
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
int head[500010],tail;
struct Edge
{
int to,next;
}edge[500010];
void add(int from,int to)
{
edge[tail].to=to;
edge[tail].next=head[from];
head[from]=tail++;
}
int in[500010],ot[500010];
int cnt;
struct node
{
int id,tm;
node(){}
node(int id,int tm)
{
this->id=id;
this->tm=tm;
}
bool operator <(node a)const
{
return tm<a.tm;
}
};
vector<node>bx[500010];
void dfs(int from,int step)
{
in[from]=++cnt;
bx[step].push_back(node(from,cnt));
for(int i=head[from];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
dfs(to,step+1);
}
ot[from]=++cnt;
}
bool num[500010][26];
char s[500010];
void create(int h)
{
int n=bx[h].size();
for(int i=0;i<n;i++)
{
if(i==0)
{
for(int j=0;j<26;j++)
num[i][j]=0;
}
else
{
for(int j=0;j<26;j++)
num[i][j]=num[i-1][j];
}
int id=bx[h][i].id-1;
num[i][s[id]-'a']^=1;
}
}
bool work(int v,int h)
{
if(bx[h].empty())
return 1;
int l=upper_bound(bx[h].begin(),bx[h].end(),node(-1,in[v]))-bx[h].begin();
if(l==bx[h].size()||bx[h][l].tm>ot[v])
return 1;
int r=lower_bound(bx[h].begin(),bx[h].end(),node(-1,ot[v]))-bx[h].begin();
l--;r--;
bool flag=0;
for(int i=0;i<26;i++)
{
bool t;
if(l<0)
t=num[r][i];
else
t=(num[l][i]^num[r][i]);
if(t&1)
{
if(flag)
return 0;
flag=1;
}
}
return 1;
}
struct Q
{
int id,v,h;
bool operator <(Q a)const
{
return h<a.h;
}
}q[500010];
bool ans[500010];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
for(int i=2;i<=n;i++)
{
int p;
scanf("%d",&p);
add(p,i);
}
scanf("%s",s);
dfs(1,1);
for(int i=0;i<m;i++)
{
scanf("%d%d",&q[i].v,&q[i].h);
q[i].id=i;
}
sort(q,q+m);
int p=-1;
for(int i=0;i<m;i++)
{
if(q[i].h!=p)
{
p=q[i].h;
create(p);
}
ans[q[i].id]=work(q[i].v,q[i].h);
}
for(int i=0;i<m;i++)
if(ans[i])
puts("Yes");
else
puts("No");
}
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 then - 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 the i-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".
codeforces 570 D Tree Requests的更多相关文章
- codeforces 570 D. Tree Requests (dfs)
题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- CF 570 D. Tree Requests
D. Tree Requests http://codeforces.com/problemset/problem/570/D 题意: 一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树 ...
- 【19.77%】【codeforces 570D】Tree Requests
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 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) 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(树上启发式合并)
570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
- Codeforces 570 - A/B/C/D/E - (Done)
链接:https://codeforces.com/contest/570 A - Elections - [水] AC代码: #include<bits/stdc++.h> using ...
随机推荐
- Python笔记(2)
Python 一些常用的运算符: 1.算术运算符:+(加).-(减).*(乘)./(除).//(取整).%(取余).**(乘方): 2.比较运算符:>(大于).<(小于).>=(大于 ...
- PatentTips - Safe general purpose virtual machine computing system
BACKGROUND OF THE INVENTION The present invention relates to virtual machine implementations, and in ...
- javascript-js中技巧集合
1.值的转换 在JavaScript中,一共有两种类型的值:原始值(primitives)和对象值(objects).原始值有:undefined, null, 布尔值(booleans), 数字(n ...
- 对Java、C#转学swift的提醒:学习swift首先要突破心理障碍。
网上非常多都说swift是一门新手友好的语言. 但以我当年从Java转学Ruby的经验,swift对于从Java.C#转来的程序猿实际并不友好.原因就在于原来总有一种错觉:一个语言最重要的就是严谨,而 ...
- 微软版UnityVs横空出世,究竟是谁成就了谁?
在移动互联网浪潮持续发力下,手游行业也异常火热.在现在的手游行业,Unity3d无疑是最耀眼的哪颗星.一直觉得Unity面向设计师是友好的,对程序猿这边并非非常友好. 2012年用Unity时开发工具 ...
- 十分钟掌握diff&patch用法
作为程序员,了解diff&patch命令是非常必要的.比如说我们发现某个项目有bug代码,而自己又没有svn的提交权限,那么此时最合适的解决方法就是用diff命令做一个补丁发给项目成员.项目成 ...
- 如何用Android studio生成正式签名的APK文件
必须签名之后才可以发布到app商店中. 平时的调试的app都有默认的签名. 下面是生成带签名的APK的步骤: 1. Build 选择 Generate Signed APK 2. 弹出框,第一次选择C ...
- ECharts 在winform中使用(访问JS)
ECharts 是百度的一个开源chart 数据统计库,采用html5 + js 编程方式. 有比较好的动态效果,功能很强大.能做出酷弦的效果. ECharts 一般用于web 开发.但winform ...
- zookeeper客户端命令行操作
一.命令行 (1)使用zookeeper安装bin目录下的./zkCli.sh连接到zookeeper服务器上,基本语法如下: ./zkCli.sh -timeout 0 -r -server ip: ...
- .NET深入解析LINQ框架1
1.LINQ简述 2.LINQ优雅前奏的音符 2.1.隐式类型 (由编辑器自动根据表达式推断出对象的最终类型) 2.2.对象初始化器 (简化了对象的创建及初始化的过程) 2.3.Lambda表达式 ( ...