【cf570】D. Tree Requests(dsu on tree)
题意:
给出一个以\(1\)为根的有根树。之后有\(m\)个询问,每个询问为\(v_i,h_i\),需要回答以\(v_i\)为根的子树中,深度为\(h_i\)的那些结点所代表的字符能否构成回文串。
思路:
静态子树询问,考虑\(dsu\ on\ tree\)。
深度可以提前处理出来。对一个子树处理时,用一个数组\(d[deep][cnt]\)来记录。
最后直接根据深度枚举判断即可。
正确性的话是基于算法本身的,我们考虑一个子树时,数组中目前只会储存这颗子树内部的信息。
/*
 * Author:  heyuhhh
 * Created Time:  2019/11/13 16:08:44
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 500005;
int n, m;
vector <int> g[N], v[N];
char s[N];
struct Q {
    int x, d, id;
}q[N];
int dep[N], sz[N];
int bson[N];
void dfs(int u, int fa, int d) {
    sz[u] = 1; dep[u] = d;
    int mx = 0;
    for(auto v : g[u]) if(v != fa) {
        dfs(v, u, d + 1);
        sz[u] += sz[v];
        if(sz[v] > mx) mx = sz[v], bson[u] = v;
    }
}
int d[N][26];
int son;
int ans[N], cnt[26];
void add(int u, int fa, int val) {
    d[dep[u]][s[u] - 'a'] += val;
    for(auto v : g[u]) if(v != fa && v != son) {
        add(v, u, val);
    }
}
void dfs2(int u, int fa, int op) {
    for(auto v : g[u]) if(v != fa && v != bson[u]) {
        dfs2(v, u, 0);
    }
    if(bson[u]) dfs2(bson[u], u, 1);
    son = bson[u];
    add(u, fa, 1);
    for(auto i : v[u]) {
        int D = q[i].d;
        int f = 0;
        for(int j = 0; j < 26; j++) if(d[D][j] & 1) ++f;
        if(f <= 1) ans[q[i].id] = 1;
    }
    son = 0;
    if(!op) add(u, fa, -1);
}
void run(){
    for(int i = 2; i <= n; i++) {
        int p; cin >> p;
        g[p].push_back(i);
        g[i].push_back(p);
    }
    cin >> (s + 1);
    for(int i = 1; i <= m; i++) {
        int x, d; cin >> x >> d;
        v[x].push_back(i);
        q[i] = Q{x, d, i};
    }
    dfs(1, 0, 1);
    dfs2(1, 0, 1);
    for(int i = 1; i <= m; i++) {
        if(ans[i]) cout << "Yes" << '\n';
        else cout << "No" << '\n';
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> m) run();
	return 0;
}
【cf570】D. Tree Requests(dsu on tree)的更多相关文章
- 【cf600】E. Lomsat gelral(dsu on tree)
		传送门 题意: 求子树众数. 思路: \(dsu\ on\ tree\)模板题,用一个桶记录即可. 感觉\(dsu\ on\ tree\)这个算法的涉及真是巧妙呀,保留重链的信息,不断暴力轻边,并且不 ... 
- 【CF1023F】Mobile Phone Network(dsu,MST)
		题意: 保证原边以边权单调非减的顺序读入 思路:先把未知边加入,再加入原始边做MST,考虑从大到小,用数据结构维护,每一条原始边相当两个链赋值操作,每一条未知边相当于一个询问,答案即为询问之和 LCT ... 
- SSAS系列——【08】多维数据(程序展现Cube)
		原文:SSAS系列--[08]多维数据(程序展现Cube) 1.引用DLL? 按照之前安装的MS SQLServer的步骤安装完成后,发现在新建的项目中“Add Reference”时居然找不到Mic ... 
- 洛谷 P3377 【模板】左偏树(可并堆)
		洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ... 
- 【BZOJ2342】双倍回文(回文树)
		[BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ... 
- 【BZOJ2337】Xor和路径(高斯消元)
		[BZOJ2337]Xor和路径(高斯消元) 题面 BZOJ 题解 我应该多学点套路: 对于xor之类的位运算,要想到每一位拆开算贡献 所以,对于每一位拆开来看 好了,既然是按位来算 我们就只需要计算 ... 
- 【BZOJ4372】烁烁的游戏(动态点分治)
		[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ... 
- 【BZOJ1013】球形空间产生器(高斯消元)
		[BZOJ1013]球形空间产生器(高斯消元) 题面 Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标, ... 
- 【LightOJ1370】Bi-shoe and Phi-shoe(欧拉函数)
		[LightOJ1370]Bi-shoe and Phi-shoe(欧拉函数) 题面 Vjudge 给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和. 题解 首先 ... 
随机推荐
- MySql 筛选条件、聚合分组、连接查询
			筛选条件 比较运算符 等于: = ( 注意!不是 == ) 不等于: != 或 <> 大于: > 大于等于: >= 小于: < 小于等于: <= IS NULL I ... 
- echarts js报错 Cannot read property 'getAttribute' of null
			本文将为您描述如何解决 eharts.js报错 Uncaught TypeError: Cannot read property 'getAttribute' of null 的问题 根据报错信息查找 ... 
- Kali设置1920x1080分辨率
			root@kali:~# xrandr --newmode -hsync +vsync root@kali:~# xrandr --addmode Virtual1 1920x1080 root@ka ... 
- 201871010109-胡欢欢《面向对象程序设计(java)》第十六周学习总结
			项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ... 
- UVA 12165 Triangle Hazard
			https://cn.vjudge.net/problem/UVA-12165 题目 给出D.E.F分BC,CA,AB的比$m_1:m_2$,$m_3:m_4$,$m_5:m_6$和PQR三点的坐标, ... 
- openjdk源码下载
			http://hg.openjdk.java.net/jdk8u/jdk8u60/jdk/file/935758609767 browse>zip 
- 使用docker运行springboot项目
			本文主要讲的是使用docker运行springboot项目 获取一个springboot项目 这里我没有重新构建,用的之前写的一个项目,直接从github上下载下来,地址:https://github ... 
- 用arthas的watch方法观察执行方法的输入输出
			watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ... 
- vue表格合并行的一个实例
			一.element控件实现 在平常的应用中,需要用到合并单元格的操作,在Excel中,这种操作很好实现,但在实际项目中,常常需要借助element控件来实现. 下面是element中的一个实例 ... 
- C语言程序设计100例之(7):级数求和
			例7 级数求和 题目描述 已知: Sn =1+1/2+1/3+…+1/n.显然对于任意一个整数 k,当 n 足够大的时候,Sn>k. 现给出一个整数 k,要求计算出一个最小的 n,使得 S ... 
