WA on Test14 求助
查看原帖
WA on Test14 求助
242317
xiaofu15191楼主2024/7/15 10:37

RT,有小数据更好。

思路:深度相同时 bfsbfs 序是连续的,同时区间的 dfsdfs 序满足在查询的子树内,直接查找字母数量判断。如果思路错了也可以告诉我为什么。谢谢。

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
string color;
long long n,m,bfn[500010],bfn_rep[500010],dfn[500010],dfn_rep[500010],cnt_bfn,cnt_dfn,dep[500010],dep_left[500010],dep_right[500010],siz[500010];
struct segtree
{
	long long sum[500010],type;
	void build()
	{
		for(long long i=1;i<=n;i++) sum[i]=sum[i-1]+(color[bfn_rep[i]]-'a'==type);
	}
	long long query(long long x,long long y)
	{
		return sum[y]-sum[x-1];
	}
}tree[26];
vector<long long>graph[500010];
void bfs()
{
	queue<pair<long long,long long>>q;
	q.push(make_pair(1,1));
	while(!q.empty())
	{
		long long from=q.front().first,now_dep=q.front().second;
		q.pop();
		bfn[from]=++cnt_bfn;
		bfn_rep[cnt_bfn]=from;
		dep_left[now_dep]=dep_left[now_dep]==0?bfn[from]:dep_left[now_dep];
		dep_right[now_dep]=bfn[from];
		dep[from]=now_dep;
		for(long long to:graph[from])
			q.push(make_pair(to,now_dep+1));
	}
}
void dfs(long long now)
{
	dfn[now]=++cnt_dfn;
	dfn_rep[cnt_dfn]=now;
	siz[now]=1;
	for(long long to:graph[now])
	{
		dfs(to);
		siz[now]+=siz[to];
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(long long i=2;i<=n;i++)
	{
		long long fa;
		cin>>fa;
		graph[fa].push_back(i);
	}
	cin>>color;
	color.insert(color.begin(),'0');
	bfs();
	dfs(1);
	for(long long i=0;i<26;i++)
	{
		tree[i].type=i;
		tree[i].build();
	}
	for(long long i=1;i<=m;i++)
	{
		long long u,h;
		cin>>u>>h;
		if(dep[u]>h)
		{
			cout<<"Yes\n";
			continue;
		}
		long long l=dep_left[h],r=dep_right[h],x=0,y=0;
		while(l<=r)
		{
			long long mid=(l+r)>>1;
			if(dfn[bfn_rep[mid]]>=dfn[u])
			{
				x=mid;
				r=mid-1;
			}
			else l=mid+1;
		}
		l=x,r=dep_right[h];
		while(l<=r)
		{
			long long mid=(l+r)>>1;
			if(dfn[bfn_rep[mid]]<=dfn[u]+siz[u]-1)
			{
				y=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		long long len=y-x+1,sum_odd=0;
		for(long long j=0;j<26;j++)
		{
			long long tmp=tree[j].query(x,y);
			if(tmp%2) sum_odd+=tmp;
		}
		if(x==0||y==0) cout<<"Yes\n";
		else if((len%2==0&&sum_odd>0)||(len%2==1&&sum_odd!=1)) cout<<"No\n";
		else cout<<"Yes\n";
	}
}
2024/7/15 10:37
加载中...