dsu on treec++
点我跳转spa
给定一个以\(1\)为根的n个节点的树,每一个点上有一个字母\((a-z)\)code
每一个点的深度定义为该节点到1号节点路径上的点数.ci
每次询问 \(a,b\), 查询以 \(a\) 为根的子树内深度为 \(b\) 的节点上的字母从新排列以后是否能构成回文串.get
重排以后可否构成回文串,即判断出现次数为奇数的字符个数是否小于等于1it
由于要屡次询问以某个点为根深度为 \(b\) 的节点上的字母class
因此能够对每一个节点开个 \(vector\) ,再把和它有关的询问保存在\(vector\)里遍历
而后在 \(dsu\) \(on\) \(tree\) 的过程进行到该节点时遍历这个节点的 \(vector\) (相关询问)查询
再对询问作判断→获得答案→保存答案sort
最后将保存的答案按照读入的顺序排个序输出便可
#include<bits/stdc++.h> #define rep(i , a , b) for(int i = a ; i <= b ; i ++) #define int long long #define pb push_back #define fi first #define se second using namespace std; const int N = 5e5 + 10; struct Edge { int nex , to; } edge[N << 2]; int head[N] , TOT; void add_edge(int u , int v) { edge[++ TOT].nex = head[u]; edge[TOT].to = v; head[u] = TOT; } int cnt[N][26] , hson[N] , sz[N] , HH; int n , m , col[N] , vis[N]; vector<pair<int ,int>>Q[N] , ans; void dfs(int u , int far) { for(int i = head[u] ; i ; i = edge[i].nex) { int v = edge[i].to; if(v == far) continue ; dfs(v , u); sz[u] += sz[v]; if(sz[v] > sz[hson[u]]) hson[u] = v; } sz[u] ++; } void calc(int u , int far , int val , int dep) { cnt[dep][col[u]] += val; for(int i = head[u] ; i ; i = edge[i].nex) { int v = edge[i].to; if(v == far || v == HH) continue ; calc(v , u , val , dep + 1); } } void dsu(int u , int far , int op , int dep) { for(int i = head[u] ; i ; i = edge[i].nex) { int v = edge[i].to; if(v == hson[u] || v == far) continue ; dsu(v , u , 0 , dep + 1); } if(hson[u]) dsu(hson[u] , u , 1 , dep + 1) , HH = hson[u]; calc(u , far , 1 , dep); for(auto i : Q[u]) { int b = i.fi , id = i.se , res = 0; rep(j , 0 , 25) { if(cnt[b][j] & 1) res ++ ; } if(res > 1) ans.pb(make_pair(id , 0)); else ans.pb(make_pair(id , 1)); } HH = 0; if(!op) calc(u , far , -1 , dep); } signed main() { cin >> n >> m; rep(i , 2 , n) { int v; cin >> v; add_edge(i , v) , add_edge(v , i); } rep(i , 1 , n) { char ch; cin >> ch; col[i] = ch - 'a'; } rep(i , 1 , m) { int a , b; cin >> a >> b; Q[a].pb(make_pair(b , i)); } dfs(1 , 0); dsu(1 , 0 , 0 , 1); sort(ans.begin() , ans.end()); for(auto i : ans) if(i.se) cout << "Yes\n" ; else cout << "No\n"; return 0; }