列表

详情


NC16547. 树的颜色

描述

给定一棵树,1为根,树上每个点有一个颜色

给q次询问,每次询问以x为根的子树中深度在[dep[x],dep[x]+y]之间的点的颜色集合(相同颜色只算一遍)中编号第k小的颜色是什么,无解输出-1

输入描述

第一行,两个数n q
第二行n-1个数,表示2到n的父亲
第三行n个数,表示n个点的颜色
接下来q行
每行三个数x y k,表示一次询问

输出描述

输出q行,对于每个询问,输出一个数表示答案

示例1

输入:

5 3
1 1 2 2
1 2 1 3 2
1 1 2
1 2 3
2 1 1

输出:

2
3
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 3075ms, 内存消耗: 80412K, 提交时间: 2022-05-05 14:56:23

#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
using namespace std;
const int N=1e5+10,INF=0x3f3f3f3f;
int ne[N*2],e[N*2],h[N],idx;
int dep[N],son[N],sz[N];
int tr[500][N];
struct Node
{
	int y,k,id;
};
int n,q;
vector<Node>Q[N];
int ans[N];
int exis[N],col[N];
int len;
void add(int a,int b)
{
	ne[idx]=h[a],e[idx]=b,h[a]=idx++;
}
int get(int x)
{
	return x/len;
}
void dfn(int u,int fa)
{
	sz[u]=1;
	dep[u]=dep[fa]+1;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		dfn(j,u);
		sz[u]+=sz[j];
		if(sz[j]>sz[son[u]])son[u]=j;
	}
}
void add(int p[N],int x,int v)
{	
	for(int i=x;i<=n;i+=lowbit(i))
		p[i]+=v;
}
int query(int p[N],int x,int y)
{
	int res=0;
	x--;
	for(int i=x;i;i-=lowbit(i))
    	res-=p[i];
    for(int i=y;i;i-=lowbit(i))
    	res+=p[i];
    return res;
}
void ud(int u)
{	
	if(exis[col[u]]<=dep[u])return;
	if(exis[col[u]]!=INF)add(tr[get(col[u])],exis[col[u]],-1);
	exis[col[u]]=dep[u];
	add(tr[get(col[u])],dep[u],1);
}
void del(int u)
{	
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		del(j);		
	}
	if(exis[col[u]]==INF)return;
	if(exis[col[u]]!=INF)add(tr[get(col[u])],exis[col[u]],-1);
	exis[col[u]]=INF;
}
void gets(int u)
{
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		gets(j);
	}
		ud(u);
	
}
void dfs(int u,int fp)
{
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j!=son[u])dfs(j,0);
	}
	if(son[u])dfs(son[u],1);
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j!=son[u])gets(j);
	}
	ud(u);
	for(int i=0;i<Q[u].size();i++)
	{
		int x=dep[u],y=x+Q[u][i].y,k=Q[u][i].k,id=Q[u][i].id;
		y=min(y,n);
		ans[id]=-1;
		for(int j=0;j<len;j++)
		{
			int sum=query(tr[j],x,y);
			if(sum<k)
			{
				k-=sum;
				continue;
			}
			for(int l=j*len;;l++)
				{
					int w=(exis[l]>=x&&exis[l]<=y);
					if(w<k){k-=w;continue;}
					ans[id]=l;break;
				}
			break;
		}
	}
	if(fp)return;del(u);
}
int main()
{
	cin>>n>>q;
	memset(h,-1,sizeof h);
	memset(exis,0x3f,sizeof exis);
	for(int i=2;i<=n;i++)
	{	int x;
		scanf("%d",&x);
		add(x,i);
	}
	len=(int)sqrt(n)+1;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&col[i]);
	}
	dep[1]=1;
	dfn(1,0);
	for(int i=1;i<=q;i++)
	{
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		Q[x].push_back({y,k,i});
	}
	dfs(1,1);
	for(int i=1;i<=q;i++)
		cout<<ans[i]<<endl;
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 1811ms, 内存消耗: 197888K, 提交时间: 2019-03-02 20:55:14

#include<bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std;
const int _=1e5+5,__=4e7+5;
int n,Q,dep[_],siz[_],son[_],ans[_],w[_],G[_],cnt,mx,num=1;
int rt[_<<2],F[_<<2],f[_],g[_],lc[__],rc[__],t[__];
struct ljq{
	int y,k,id;
};
vector<int>e[_];
vector<ljq>q[_];
void dfs(int u){
	siz[u]=1;
	for(int v:e[u]){
		dep[v]=dep[u]+1;
		dfs(v);siz[u]+=siz[v];
		if(siz[son[u]]<siz[v])son[u]=v;
	}
}
void NEW(int &no){
	++cnt;t[cnt]=t[no];
	lc[cnt]=lc[no];	rc[cnt]=rc[no];
	no=cnt;
}
void modify(int &no,int l,int r,int k,int x){
	if(!no)NEW(no);t[no]+=x;
	if(l==r)return;
	if(k<=mid)modify(lc[no],l,mid,k,x);
	else modify(rc[no],mid+1,r,k,x);
}
void update(int no,int l,int r,int k,int x,int opt){
	if(F[no]!=num)F[no]=num,rt[no]=0;
	modify(rt[no],1,n,x,opt);
	if(l==r)return;
	if(k<=mid)update(no<<1,l,mid,k,x,opt);
	else update(no<<1|1,mid+1,r,k,x,opt);
}
int Query(int no,int l,int r,int k){
	if(!no||l==r)return t[no];
	if(k<=mid)return Query(lc[no],l,mid,k);
	else return t[lc[no]]+Query(rc[no],mid+1,r,k);
}
int query(int no,int l,int r,int k,int x){
	if(l==r)return k-(g[l]==num&&f[l]<=x)==0?l:-1;
	if(F[no<<1]!=num)F[no<<1]=num,rt[no<<1]=0;
	int s=Query(rt[no<<1],1,n,x);
	if(s>=k)return query(no<<1,l,mid,k,x);
	else return query(no<<1|1,mid+1,r,k-s,x);
}
void insert(int x,int y){
	if(g[x]!=num)g[x]=num,f[x]=y,update(1,1,n,x,y,1);
	if(y<f[x]){
		update(1,1,n,x,f[x],-1);
		update(1,1,n,x,y,1);
		f[x]=y;
	}
}
void clear(){cnt=0;num++;}
queue<int>qu;
void bfs(int x){
	qu.push(x);
	while(!qu.empty()){
		int u=qu.front();qu.pop();
		insert(w[u],dep[u]);
		for(int v:e[u])qu.push(v);
	}
}
void Dfs(int u){
	for(int v:e[u])if(v!=son[u])Dfs(v),clear();
	if(son[u])Dfs(son[u]); insert(w[u],dep[u]);
	for(int v:e[u])if(v!=son[u])bfs(v);
	for(ljq x:q[u])ans[x.id]=query(1,1,n,x.k,dep[u]+x.y);
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>Q;
	for(int i=2;i<=n;++i){
		int x;cin>>x;
		e[x].push_back(i);
	}
	for(int i=1;i<=n;++i)cin>>w[i],assert(w[i]>=1&&w[i]<=n);
	for(int i=1;i<=Q;++i){
		int x,y,k;cin>>x>>y>>k;
		q[x].push_back((ljq){y,k,i});
	}
	dep[1]=1;dfs(1);Dfs(1);
	for(int i=1;i<=Q;++i)cout<<ans[i]<<endl;
	return 0;
}

上一题