#48TLE不知道为什么,复杂度理论能过
查看原帖
#48TLE不知道为什么,复杂度理论能过
637073
wujingfey楼主2023/7/26 15:38
#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
const int N=5e5+10;
int n,q;
char c[N];
vector<pii> qry[N];
vector<int> e[N];
map<int,bitset<26> > m[N];
bool ans[N];
void dfs(int u,int dep){
	for(auto v:e[u]){
		dfs(v,dep+1);
		if(m[v].size()>m[u].size()) swap(m[u],m[v]);
		for(auto p:m[v]){//转移v为根的子树内的所有dep的所有字符出现次数 
			if(m[u].find(p.first)==m[u].end()) 
				m[u][p.first] = bitset<26>(0);
			m[u][p.first] ^= p.second;
		}
	}
	m[u][dep] = bitset<26>(0);
	m[u][dep][c[u]-'a']=1;
	for(auto q:qry[u]){
		int d=q.first,idx=q.second,cnt=0;
		if(m[u].find(d)!=m[u].end()) cnt=m[u][d].count();
		if(cnt<=1) ans[idx]=1;
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
	for(int i=2;i<=n;i++){
		int a;
		cin>>a;
		e[a].push_back(i);
	}
	cin>>(c+1);
	for(int i=1;i<=q;i++){
		int a,b;
		cin>>a>>b;
		qry[a].push_back({b,i});//离线询问 
	}
	dfs(1,1);
	for(int i=1;i<=q;i++){
		cout<<(ans[i]?"Yes":"No")<<endl;
	}
	return 0;
} 

思路是启发式合并,用map[v][k]map[v][k]表示以vv为根向下走k的深度不同字符有多少个,

2023/7/26 15:38
加载中...