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 ...
随机推荐
- 异常值(outlier)
简介 在数据挖掘的过程中,我们可能会经常遇到一些偏离于预测趋势之外的数据,通常我们称之为异常值. 通常将这样的一些数据的出现归为误差.有很多情况会出现误差,具体的情况需要就对待: 传感器故障 -> ...
- 倍增算法总结 ( 含RMQ模板)
部分题目来自<算法竞赛设计进阶> 问题 给定一个长度为n的数列A,有m个询问,每次给定一个整数T,求出最大的k,满足a[1],a[2]……a[k]的和小于等于T(不会打sigm ...
- mybatis中sql标签和include标签
1.首先定义一个sql标签,一定要定义唯一id.(name,age是要查询的字段) <sql id="Base_Column_List" >name,age</s ...
- java.lang.RuntimeException: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
这种情况可能是因为在设置数据库的时候,没有配置数据库的方言,导致sql语句无法被识别. 例如在配置Jfinal的配置文件的时候 如果不配置数据库的方言,默认下它是MySQL的,当使用oracle数据库 ...
- Opencv 视频转为图像序列
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50283303 基于OpenCV的视频转 ...
- 【Android】桌面歌词悬浮效果简单实现
在使用"网易云音乐"的时候,发现有一个显示"桌面歌词"的功能,于是就想着自己实现下.查了下资料,是用WindowManage实现的.实现过程中也出现了些问题,看 ...
- 【POJ 1850】 Code
[POJ 1850] Code 还是非常想说 数位dp真的非常方便! !. 数位dp真的非常方便!.! 数位dp真的非常方便! !! 重要的事说三遍 该题转换规则跟进制差点儿相同 到z时进一位 如az ...
- poj 3259 bellman最短路推断有无负权回路
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36717 Accepted: 13438 Descr ...
- linux中sed的使用方法具体解释(对行数据的加入、删除等)
sed使用语法 [root@fwq test]# sed --help 使用方法: sed [选项]... {脚本(假设没有其它脚本)} [输入文件]... -n, --quiet, --silent ...
- scikit-learn:3.5. Validation curves: plotting scores to evaluate models
參考:http://scikit-learn.org/stable/modules/learning_curve.html estimator's generalization error can b ...