[cf375D]Tree and Queries
Description
给定一棵树,每个节点有颜色。t个询问,求以v为根的子树中有多少种颜色满足该颜色的节点个数>k。
Solution
dfs序+莫队。
#include<bits/stdc++.h> using namespace std; const int N=100005; struct graph{ int nxt,to; }e[N<<1]; struct query{ int l,r,k,n; }q[N]; int fro[N],beh[N],num[N];//dfs序 int f[N],s[N],tmp[N];//莫队 tmp[i]:s[x]>=i的x的个数 int g[N],c[N],ans[N],n,m,t,cnt; void adde(int x,int y){ e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y; } void dfs(int u){ fro[u]=++cnt;num[cnt]=u; for(int i=g[u];i;i=e[i].nxt) if(!fro[e[i].to]){ dfs(e[i].to); } beh[u]=cnt; } bool cmp(query a,query b){ if(f[a.l]!=f[b.l]) return f[a.l]<f[b.l]; return a.r<b.r; } void add(int i){ ++s[c[num[i]]]; ++tmp[s[c[num[i]]]]; } void remove(int i){ --tmp[s[c[num[i]]]]; --s[c[num[i]]]; } int main(){ // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%d%d",&n,&t); 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); adde(x,y);adde(y,x); } cnt=0;dfs(1); for(int i=1,v;i<=t;++i){ scanf("%d%d",&v,&q[i].k); q[i].l=fro[v];q[i].r=beh[v];q[i].n=i; } m=sqrt(n); for(int i=1,k=1;i<=n;++k) for(int j=1;i<=n&&j<=m;++i,++j) f[i]=k; sort(q+1,q+1+t,cmp); int l=1,r=1; ++s[c[num[1]]];++tmp[1]; for(int i=1;i<=t;++i){ while(r<q[i].r){ ++r;add(r); } while(r>q[i].r){ remove(r);--r; } while(l>q[i].l){ --l;add(l); } while(l<q[i].l){ remove(l);++l; } ans[q[i].n]=tmp[q[i].k]; } for(int i=1;i<=t;++i) printf("%d\n",ans[i]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
2017-01-06 [模板]平面最近点对