欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces - Tree and Queries

程序员文章站 2022-05-27 20:05:24
...

题目链接:Codeforces - Tree and Queries


子树问题,我们可以考虑dfs序。

然后发现区间之间可以O(1)更新答案,所以直接莫队即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,m,res[N],sum[N],cl=1,cr,c[N],st[N],ed[N],dfn[N],cnt,bl,num[N];
struct node{int l,r,k,id;}t[N];
vector<int> g[N];
inline void ade(int a,int b){g[a].push_back(b),g[b].push_back(a);}
int cmp(node a,node b){return a.l/bl==b.l/bl?a.r<b.r:a.l<b.l;}
void dfs(int x,int fa){
	st[x]=++cnt; dfn[cnt]=x;
	for(auto to:g[x])	if(to!=fa)	dfs(to,x);
	ed[x]=cnt;
}
inline void add(int x){sum[++num[c[x]]]++;}
inline void del(int x){sum[num[c[x]]--]--;}
signed main(){
	cin>>n>>m;	bl=sqrt(n);
	for(int i=1;i<=n;i++)	scanf("%d",&c[i]);
	for(int i=1,x,y;i<n;i++)	scanf("%d %d",&x,&y),ade(x,y);
	dfs(1,1);
	for(int i=1,v,k;i<=m;i++)	scanf("%d %d",&v,&k),t[i]={st[v],ed[v],k,i};
	sort(t+1,t+1+m,cmp);
	for(int i=1,L,R;i<=m;i++){
		L=t[i].l,R=t[i].r;
		while(L<cl)	add(dfn[--cl]);
		while(R>cr)	add(dfn[++cr]);
		while(L>cl)	del(dfn[cl++]);
		while(R<cr)	del(dfn[cr--]);
		res[t[i].id]=sum[t[i].k];
	}
	for(int i=1;i<=m;i++)	printf("%d\n",res[i]);
	return 0;
}