HDU Boring counting 树状数组

来源:互联网 发布:c语言的架构 编辑:程序博客网 时间:2024/05/16 10:12
//树状数组区间更新//树形结构->线性结构DFS处理//求区间有K个相同的有多少数字//每个节点表示到i的区间有几个K相同值#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>using namespace std;const int maxn=100005;int B[maxn];int val[maxn];int vx[maxn];int L[maxn];int map[maxn];int R[maxn];int ans[maxn];int n,m;int tot;void update(int id,int val){for(int i=id;i<maxn;i+=(i&-i))B[i]+=val;}int sum(int id){int ret=0;for(int i=id;i>0;i-=(i&-i))ret+=B[i];return ret;}vector<int >edge[maxn];vector<int >len[maxn];struct Q{int id;int r,l;bool operator < (const Q &t )const {return r<t.r;}}p[maxn];void dfs(int u,int f){int sz=edge[u].size();map[tot]=u;L[u]=tot++;for(int i=0;i<sz;i++){int v=edge[u][i];if(v==f)continue;dfs(v,u);}R[u]=tot;}int main(){int T,q;int i,j;int u,v;scanf("%d",&T);for(int cas=1;cas<=T;cas++){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&val[i]); vx[i-1]=val[i]; } sort(vx,vx+n); int cnt=unique(vx,vx+n)-vx; for(i=1;i<=n;i++) val[i]=lower_bound(vx,vx+cnt,val[i])-vx; for(i=0;i<=n;i++)edge[i].clear(),len[i].clear(); for(i=1;i<n;i++){scanf("%d%d",&u,&v);edge[u].push_back(v);edge[v].push_back(u); }  tot=1; dfs(1,-1); scanf("%d",&q); for(i=0;i<q;i++){scanf("%d",&u);p[i].id=i;p[i].r=R[u];p[i].l=L[u]; } for(i=0;i<cnt;i++) len[i].push_back(0); memset(B,0,sizeof(B)); sort(p,p+q);  for(i=1,j=0;i<tot;i++){ int t=val[map[i]]; len[t].push_back(i); int sz=len[t].size()-1; if(sz>=m){update(len[t][sz-m]+1,1);update(len[t][sz-m+1]+1,-1); } if(sz>m){update(len[t][sz-m-1]+1,-1);update(len[t][sz-m]+1,1); } while(j<q && p[j].r-1==i){ans[p[j].id]=sum(p[j].l);j++; } } if(cas!=1)puts(""); printf("Case #%d:\n",cas); for(i=0;i<q;i++) printf("%d\n",ans[i]);}return 0;}