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