线段树合并只过样例求调教(悬一关)
查看原帖
线段树合并只过样例求调教(悬一关)
754502
_AyachiNene楼主2023/12/1 23:29
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int res=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
	return res*f;
}
void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
struct node
{
	int nxt,to;
}e[500005];
int head[500005],cnt_edge;
void add(int u,int v)
{
	e[++cnt_edge].to=v;
	e[cnt_edge].nxt=head[u];
	head[u]=cnt_edge;
}
struct Query
{
	int id,k;
};
vector<Query>q[500005];
int n,m;
int f[500005];
int dep[500005];
int a[500005];
int ans[500005];
//------SegmentTreeBegin-----
int rt[500005];
struct segt
{
	int ls,rs;
	int bucket;
}t[12000000];
#define mid ((l+r)>>1)
int cnt;
void update(int root)
{
	t[root].bucket=t[t[root].ls].bucket^t[t[root].rs].bucket;
}
int insert(int x,int l,int r,int root,int k)
{
	if(!root)
		root=++cnt;
	if(l==r)
	{
		t[root].bucket^=(1<<k);
		return root;
	}
	if(x<=mid)
		t[root].ls=insert(x,l,mid,t[root].ls,k);
	else
		t[root].rs=insert(x,mid+1,r,t[root].rs,k);
	update(root);
	return root;
}
int merge(int x,int y,int l,int r)
{
	if(!x||!y)
		return x|y;
	if(l==r)
	{
		t[x].bucket^=t[y].bucket;
		return x;
	}
	t[x].ls=merge(t[x].ls,t[y].ls,l,mid);
	t[x].rs=merge(t[x].rs,t[y].rs,mid+1,r);
	update(x);
	return x;
}
int query(int x,int l,int r,int root)
{
	if(!root)
		return 0;
	if(l==r)
	{
		int res=0,x=t[root].bucket;
		while(x)
		{
			if(x&1)
				++res;
			x>>=1;
		}
		return res<=1;
	}
	if(x<=mid)
		return query(x,l,mid,t[root].ls);
	else
		return query(x,mid+1,r,t[root].rs);
}
//--------SegmentTreeEnd-----
void dfs1(int u)
{
	dep[u]=dep[f[u]]+1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		dfs1(v);
	}
}
void dfs2(int u)
{
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		dfs2(v);
		rt[u]=merge(rt[u],rt[v],1,5e5);
	}
	for(int i=0;i<q[u].size();i++)
		ans[q[u][i].id]=query(dep[u]+q[u][i].k,1,5e5,rt[u]);
}
int main()
{
	n=read(),m=read();
	for(int i=2;i<=n;i++)
	{
		f[i]=read();
		add(f[i],i);
	}
	for(int i=1;i<=n;i++)
	{
		char x;
		cin>>x;
		a[i]=x-'a'+1;
	}
	dfs1(1);
	for(int i=1;i<=n;i++)
		rt[i]=insert(dep[i],1,5e5,rt[i],a[i]);
	for(int i=1;i<=m;i++)
	{
		int u=read(),k=read();
		--k;
		q[u].push_back((Query){i,k});
	}
	dfs2(1);
	for(int i=1;i<=m;i++)
		if(ans[i])
			puts("Yes");
		else
			puts("No");
}
2023/12/1 23:29
加载中...