570D - Tree Requests

题意

给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串。

分析

一个数组 \(C[i][j]\) 表示深度为 \(i\) 字母为 \(j\) 的数量,数组 \(odd[i]\) 表示深度为 \(i\) 时出现次数为奇数的字母种数。

如果想要构成回文串,那么某一深度下出现的次数为奇数的字母不能超过一种,注意如果字符串长度为 0 也叫回文串。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 5e5 + 10;
int n;
int fa[MAXN], son[MAXN], dep[MAXN], siz[MAXN];
int col[MAXN];
int cnt, head[MAXN];
struct Edge {
int to, next;
} e[MAXN << 1];
struct Ex {
int x, c;
};
vector<Ex> ex[MAXN];
void addedge(int u, int v) {
e[cnt].to = v; e[cnt].next = head[u]; head[u] = cnt++;
e[cnt].to = u; e[cnt].next = head[v]; head[v] = cnt++;
}
void dfs(int u) {
siz[u] = 1;
son[u] = 0;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to != fa[u]) {
fa[e[i].to] = u;
dep[e[i].to] = dep[u] + 1;
dfs(e[i].to);
if(siz[e[i].to] > siz[son[u]]) son[u] = e[i].to;
siz[u] += siz[e[i].to];
}
}
}
int vis[MAXN], ans[MAXN];
int mk[MAXN];
int C[MAXN][30], odd[MAXN], num[MAXN];
void change(int u, int c) {
C[dep[u]][mk[u]] += c;
num[dep[u]] += c;
if(C[dep[u]][mk[u]] & 1) odd[dep[u]]++;
else odd[dep[u]]--;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to != fa[u] && !vis[e[i].to]) change(e[i].to, c);
}
}
void dfs1(int u, int flg) {
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to != fa[u] && e[i].to != son[u]) dfs1(e[i].to, 1);
}
if(son[u]) {
dfs1(son[u], 0);
vis[son[u]] = 1;
}
change(u, 1);
int sz = ex[u].size();
for(int i = 0; i < sz; i++) {
ans[ex[u][i].x] = (odd[ex[u][i].c] <= 1 || num[ex[u][i].c] == 0);
}
if(son[u]) vis[son[u]] = 0;
if(flg) change(u, -1);
}
char ss[MAXN];
int main() {
int m;
scanf("%d%d", &n, &m);
memset(head, -1, sizeof head);
cnt = 0;
dep[1] = 1;
for(int i = 2; i <= n; i++) {
int x;
scanf("%d", &x);
addedge(i, x);
}
scanf("%s", ss);
for(int i = 0; i < n; i++) {
mk[i + 1] = ss[i] - 'a';
}
dfs(1);
for(int i = 0; i < m; i++) {
int x, y;
scanf("%d%d", &x, &y);
ex[x].push_back(Ex{i, y});
}
dfs1(1, 0);
for(int i = 0; i < m; i++) {
puts(ans[i] ? "Yes" : "No");
}
return 0;
}

Codeforces 570D - Tree Requests(树上启发式合并)的更多相关文章

  1. Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

    http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...

  2. codeforces 375D . Tree and Queries 启发式合并 || dfs序+莫队

    题目链接 一个n个节点的树, 每一个节点有一个颜色, 1是根节点. m个询问, 每个询问给出u, k. 输出u的子树中出现次数大于等于k的颜色的数量. 启发式合并, 先将输入读进来, 然后dfs完一个 ...

  3. Codeforces 570D TREE REQUESTS dfs序+树状数组

    链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...

  4. Codeforces 570D - Tree Requests【树形转线性,前缀和】

    http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和 ...

  5. CodeForces 570D - Tree Requests - [DFS序+二分]

    题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根 ...

  6. codeforces 570D.Tree Requests

    [题目大意]: 给定一棵树,树的每个节点对应一个小写字母字符,有m个询问,每次询问以vi为根节点的子树中,深度为hi的所有节点对应的字符能否组成一个回文串: [题目分析]: 先画个图,可看出每次询问的 ...

  7. 总结-DSU ON TREE(树上启发式合并)

    考试遇到一道题: 有一棵n个点的有根树,每个点有一个颜色,每次询问给定一个点\(u\)和一个数\(k\),询问\(u\)子是多少个不同颜色节点的\(k\)级祖先.n<=500000. 显然对每一 ...

  8. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  9. 神奇的树上启发式合并 (dsu on tree)

    参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...

随机推荐

  1. Django笔记 —— 模板

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  2. 《算法》C++代码 前言

    现在大二正在上<数据结构>课,课内的书上代码实现很喜欢无脑用类.变量名字很长,而且常常实现太繁琐,并且代码有些无法运行,这些对于老手无所谓,但初学者看起来却会很不舒服.因此写点自己的代码, ...

  3. JAVA中的类

    节选自:http://www.cnblogs.com/dolphin0520/p/3811445.html 1. 成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一 ...

  4. isinstance()判断数据类型

    判断数据类型isinstance()l=[1,2,3]print(isinstance(l,list))#括号里面第一个填需要判断的数据,第二个是判断条件

  5. Entity Framework(四)--EF原理和状态管理

    一.原理: 如何查看真正执行的SQL是怎样的? DbContext有一个Database属性,Database属性有一个Log属性,是Action委托类型其中的参数就是sql语句,每次EF执行sql语 ...

  6. 孤荷凌寒自学python第二十三天python类的封装

    孤荷凌寒自学python第二十三天python类的封装 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.从怎么样访问类的内部代码块中定义的私有属性说起 类中定义的私有属性和私有方法是无法被 ...

  7. 孤荷凌寒自学python第八天 初识Python的序列之元组

    孤荷凌寒自学python第八天 Python的序列之元组 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) (同步音频笔记:https://www.ximalaya.com/keji/19103 ...

  8. 第十五篇:jQuery

    本篇内容 简介 使用 一. 简介 jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. jQuery 很容易学习. jQuery 库可以通过一行简 ...

  9. Codeforces Round #386 (Div. 2) 746G(树的构造)

    大体题意 一棵树有n个结点,告诉你每层深度上有a[i]个结点,以及有多少叶子结点 让你生成这棵树 题解:考虑一颗树,如果满足每层深度上有a[i]结点,最多能有多少叶子结点 那么答案很简单,就是对(a[ ...

  10. 雅礼集训 Day1 T2 折射

    折射 题目描述 小\(\mathrm{Y}\)十分喜爱光学相关的问题,一天他正在研究折射. 他在平面上放置了\(n\)个折射装置,希望利用这些装置画出美丽的折线. 折线将从某个装置出发,并且在经过一处 ...