题意:给定了一棵树和树上每一个节点的权值 然后询问是给出子树顶点求子树中出现k次的节点权值的个数
解法:把树形先转化成线性的 然后离线所有询问 不要忘了把树上节点的权值离散化 弄完之后就直接往
扫就可以了 当某一种权值>=k时才进行维护
#pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define maxn 111111
vector<int>g[maxn];
int L[maxn],R[maxn],tot,val[maxn],num[maxn],head[maxn],vis[maxn],n;
void dfs(int u,int f){
L[u]=++tot;
num[tot]=val[u];
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(v==f)continue;
dfs(v,u);
}
R[u]=tot;
}
struct node{
int v,l,r,id;
}_q[maxn];
int cmp(node x,node y){return x.r<y.r;}
int add[maxn<<2];
inline void down(int rt){
if(add[rt]){
add[ls]+=add[rt],add[rs]+=add[rt];
add[rt]=0;
}
}
inline void build(int rt,int l,int r){
add[rt]=0;if(l==r)return ;
build(ls,l,mid);
build(rs,mid+1,r);
}
inline void ins(int rt,int l,int r,int L,int R,int w){
if(L<=l&&r<=R){add[rt]+=w;return ;}
down(rt);
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
}
inline int query(int rt,int l,int r,int pos){
if(l==r)return add[rt];
down(rt);
if(pos<=mid)return query(ls,l,mid,pos);
return query(rs,mid+1,r,pos);
}
int x[maxn];
vector<int>pos[maxn];
int ans[maxn];
int main() {
int t,_=0,k,u,v,q;
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&k);
tot=0;
rep(i,1,n){
scanf("%d",&val[i]),x[i]=val[i];
g[i].clear(),pos[i].clear();
}
rep(i,1,n-1){
scanf("%d%d",&u,&v);
g[u].push_back(v),g[v].push_back(u);
}
sort(x+1,x+1+n);
int cnt=(int)(unique(x+1,x+n+1)-x-1);
for(int i=1;i<=n;i++)val[i]=(int)(lower_bound(x+1,x+cnt+1,val[i])-x);
dfs(1,-1);
scanf("%d",&q);
rep(i,0,q-1){
scanf("%d",&_q[i].v);
_q[i].l=L[_q[i].v];_q[i].r=R[_q[i].v];
_q[i].id=i;
}
sort(_q,_q+q,cmp);build(1,1,tot);
int cur=0;
rep(i,1,tot){
int va=num[i];
pos[va].push_back(i);
int sz=(int)pos[va].size();
if(sz>=k){
if(sz==k)ins(1,1,tot,1,pos[va][sz-k],1);
else{
ins(1,1,tot,1,pos[va][sz-k-1],-1);
ins(1,1,tot,pos[va][sz-k-1]+1,pos[va][sz-k],1);
}
}
while(cur<q&&_q[cur].r==i){
ans[_q[cur].id]=query(1,1,tot,_q[cur].l);
++cur;
}
}
if(_)puts("");
printf("Case #%d:\n",++_);
rep(i,0,q-1)printf("%d\n",ans[i]);
}
return 0;
}