Codeforces570D Tree Requests

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

最後將保存的答案按照讀入的順序排個序輸出便可

AC_Code

#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;
}
相關文章
相關標籤/搜索