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;
}

D. Tree Requests

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

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 vihi.
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.

Input

The first line contains two integers nm (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 vihi (1?≤?vi,?hi?≤?n)
— the vertex and the depth that appear in thei-th query.

Output

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).

Sample test(s)

input

6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2

output

Yes
No
Yes
Yes
Yes

Note

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".

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-22 03:48:09

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 limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of?n?vertices. Each vertex contains a lowercase

POJ-3321 Apple Tree 【DFS序+树状数组】

Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree. The tree has N forks which are connected by branches.

poj3321-Apple Tree(DFS序+树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36442   Accepted: 10894 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has bee

POJ 3321:Apple Tree(dfs序+树状数组)

题目大意:对树进行m次操作,有两类操作,一种是改变一个点的权值(将0变为1,1变为0),另一种为查询以x为根节点的子树点权值之和,开始时所有点权值为1. 分析: 对树进行dfs,将树变为序列,记录每个点进栈出栈的时间戳作为其对应区间的左右端点,那么其子节点对应区间必在该区间内,对这段区间求和即可,用树状数组进行修改与求和. 代码: program apple; type point=^node; node=record x:longint; next:point; end; var a:arra

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/problem/C Description Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numb

HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形dp, 对于每条链u,v,w,我们只在lca(u,v)的顶点上处理它 让dp[i]表示以i为根的指数的最大值,sum[i]表示dp[vi]的和(vi为i的儿子们) 则i点有两种决策,一种是不选以i为lca的链,则dp[i]=sum[i]. 另一种是选一条以i为lca的链,那么有转移方程:dp[i]=

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些

BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状数组维护, DFS到的查询点就回答询问.时间复杂度O(|ACAM|+QlogQ) ------------------------------------------------------------------------------------------- #include<cstdio>

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要