Codeforces 570D TREE REQUESTS dfs序+树状数组
题解链接:点击打开链接
题意:
给定n个点的树。m个询问
以下n-1个数给出每一个点的父节点,1是root
每一个点有一个字母
以下n个小写字母给出每一个点的字母。
以下m行给出询问:
询问形如 (u, deep) 问u点的子树中,距离根的深度为deep的全部点的字母是否能在随意排列后组成回文串,能输出Yes.
思路:dfs序,给点又一次标号,dfs进入u点的时间戳记为l[u], 离开的时间戳记为r[u], 这样对于某个点u,他的子树节点相应区间都在区间 [l[u], r[u]]内。
把距离根深度同样的点都存到vector里 D[i] 表示深度为i的全部点,在dfs时能够顺便求出。
把询问按深度排序,query[i]表示全部深度为i的询问。
接下来依照深度一层层处理。
对于第i层,把全部处于第i层的节点都更新到26个树状数组上。
然后处理询问,直接查询树状数组上有多少种字母是奇数个的。显然奇数个字母的种数要<=1
处理完第i层,就把树状数组逆向操作。相当于清空树状数组
注意的一个地方就是 询问的深度是随意的,也就是说可能超过实际树的深度,也可能比当前点的深度小。
。
所以须要初始化一下答案。。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <vector>
#include <string>
#include <time.h>
#include <math.h>
#include <iomanip>
#include <queue>
#include <stack>
#include <set>
#include <map>
const int inf = 1e9;
const double eps = 1e-8;
const double pi = acos(-1.0);
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) pt(x / 10);
putchar(x % 10 + '0');
}
using namespace std;
const int N = 5e5 + 100;
typedef long long ll;
typedef pair<int, int> pii;
struct BIT {
int c[N], maxn;
void init(int n) { maxn = n; memset(c, 0, sizeof c); }
inline int Lowbit(int x) { return x&(-x); }
void change(int i, int x)//i点增量为x
{
while (i <= maxn)
{
c[i] += x;
i += Lowbit(i);
}
}
int sum(int x) {//区间求和 [1,x]
int ans = 0;
for (int i = x; i >= 1; i -= Lowbit(i))
ans += c[i];
return ans;
}
int query(int l, int r) {
return sum(r) + sum(l - 1);
}
}t[26];
int n, m;
char s[N];
vector<int>G[N], D[N];
int l[N], r[N], top;
vector<pii>query[N];
bool ans[N];
void dfs(int u, int fa, int dep) {
D[dep].push_back(u);
l[u] = ++top;
for (auto v : G[u])
if (v != fa)dfs(v, u, dep + 1);
r[u] = top;
}
int main() {
rd(n); rd(m);
fill(ans, ans + m + 10, 1);
for (int i = 0; i < 26; i++) t[i].init(n);
for (int i = 2, u; i <= n; i++)rd(u), G[u].push_back(i);
top = 0;
dfs(1, 1, 1);
scanf("%s", s + 1);
for (int i = 1, u, v; i <= m; i++) {
rd(u); rd(v); query[v].push_back(pii(u, i));
}
for (int i = 1; i <= n; i++)
{
if (D[i].size() == 0)break;
for (auto v : D[i]) t[s[v] - 'a'].change(l[v], 1); for (pii Q : query[i])
{
int ou = 0;
for (int j = 0; j < 26; j++)
{
if (t[j].query(l[Q.first], r[Q.first]))
ou += t[j].query(l[Q.first], r[Q.first]) & 1;
}
ans[Q.second] = ou <= 1;
}
for (auto v : D[i]) t[s[v] - 'a'].change(l[v], -1);
}
for (int i = 1; i <= m; i++)ans[i] ? puts("Yes") : puts("No"); return 0;
}
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".
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 ...
- poj3321-Apple Tree(DFS序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36442 Accepted: 10894 Desc ...
- pku-3321 Apple Tree(dfs序+树状数组)
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...
- POJ 3321 Apple Tree(dfs序树状数组)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10486 题意:一颗有n个分支的苹果树,根为1,每个分支只有一个苹果,给出n- ...
- POJ 3321:Apple Tree(dfs序+树状数组)
题目大意:对树进行m次操作,有两类操作,一种是改变一个点的权值(将0变为1,1变为0),另一种为查询以x为根节点的子树点权值之和,开始时所有点权值为1. 分析: 对树进行dfs,将树变为序列,记录每个 ...
- CodeForces 570D - Tree Requests - [DFS序+二分]
题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根 ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
随机推荐
- linux中udev简单的用法【转】
本文转载自:http://blog.csdn.net/qq_29729577/article/details/50825134 udev是Linux提供的一种在用户态管理设备的一种机制,udev的详细 ...
- nyoj 21--三个水杯(隐式图bfs)
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识 ...
- 函数和指针 C++
一.用函数指针变量调用函数. 指针变量也可以指向一个函数,一个函数在编译时被分配给一个入口地址.这个函数入口地址就称为函数的指针.可以用一个指针变量指向函数,然后通过该指针变量调用此函数. 定义指向函 ...
- 使用python进行re拆分网页内容
这里简短的总结一下而不是完全的罗列python的re模块,python的re具有强大的功能,如下是一个从我们学校抓取数据然后拆分的程序,代码如下: import httplib import urll ...
- 小程序:前端防止用户重复提交&即时消息(IM)重复发送问题解决
背景: 最近参与开发的小程序,涉及到即时消息(IM)发送的功能: 聊天界面如下,通过键盘上的[发送]按钮,触发消息发送功能 问题发现: 功能开发完毕,进入测试流程:测试工程师反馈说: 在Android ...
- C - Young Physicist
Problem description A guy named Vasya attends the final grade of a high school. One day Vasya decide ...
- 用 Swift 开发一个 TODO 应用
背景 相信不少 iOS 程序员对于 Swift 依旧持以观望的态度,一来是这小家伙刚出来没几天,本身还处于完善的阶段:二来是学习的成本较高,看完官方文档怎么也要个几天的时间:三来是反正最近几年很难在工 ...
- 第6章 服务模式 Service Interface(服务接口)
Service Interface(服务接口) 上下文 您正在设计企业应用程序,并且需要能够通过网络使用其部分功能.此功能需要能够被各类系统使用,因此互操作性是设计的重要方面.除互操作性之外,可能还需 ...
- Install opencv on Centos
研究centos 有很长一段时间了,一直没有写过这方面的感觉,今天在看到网友的一篇文章时,结合亲身体会就下面安装opencv的一些步骤与大家共享. CentOS OpenCV已被广泛应用但是也在不断的 ...
- 第一课 导入库 - 创建数据集 - CSV读取 - 导出 - 查找最大值 - 绘制数据
第1课 创建数据 - 我们从创建自己的数据集开始分析.这可以防止阅读本教程的最终用户为得到下面的结果而不得不下载许多文件.我们将把这个数据集导出到一个文本文件中,这样您就可以获得从文本文件中一些拉取数 ...