这题好题啊.
我发现我没有写过莫队算法的博客.以后我会把博客加上去的.
先看看这题吧.
Codeforces 375D Tree and Queries
给一棵[Math Processing Error]
1
为根的树,每个节点有一种颜色,个询问,询问[Math Processing Error]
v
为根的子树中出现次数的颜色有多少种.
只有询问.我们考虑莫队.
只有子树.我们考虑dfs序.
以1为根跑出dfs序并重新编号,用dfn和edf两个数组标明每个点控制的子树.
接下来莫队离线排序搞一下,用cnt数组维护每一种颜色出现的次数.
sum数组维护每一种颜色出现的次数分别出现的次数.(这个说法比较诡异).
然后按照莫队处理一下就可以了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
re0 x=0,f=1;rec c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=x*10+c-'0';
return x*(f?1:-1);
}
inline void read(rel &x){
x=0;re0 f=1;rec c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=x*10+c-'0';
x*=f?1:-1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return pc(48);
if (x<0) x=-x,pc('-');
re0 bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
}
inline char fuhao(){
rec c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=1e5;
typedef int fuko[yuzu|10];
vector<int> lj[yuzu|10];
fuko a,dfn,edf,cnt,ans,sum,col;
int n=read(),m=read(),id,block=sqrt(n);
#define bl(x) ((x)/block)
#define all(u) dfn[u],edf[u]
void dfs(int u,int fa){
dfn[u]=++id;
col[id]=u;
for (int v:lj[u]) if (v^fa) dfs(v,u);
edf[u]=id;
}
struct query{
int l,r,k,id;
bool operator <(const query &b) const{
return bl(l)^bl(b.l)?l<b.l:r<b.r;
}
}q[yuzu|10];
int nowl=1,nowr;
void add(int x){sum[++cnt[a[col[x]]]]++;}
void del(int x){sum[cnt[a[col[x]]]--]--;}
int main(){
re0 i;
for (i=1;i<=n;++i) a[i]=read();
for (i=1;i<n;++i){
int u=read(),v=read();
lj[u].push_back(v);
lj[v].push_back(u);
}
dfs(1,0);
for (i=1;i<=m;++i){
int u=read(),k=read();
q[i]=query{all(u),k,i};
}
sort(q+1,q+m+1);
for (i=1;i<=m;++i){
for (;nowl<q[i].l;) del(nowl++);
for (;nowl>q[i].l;) add(--nowl);
for (;nowr<q[i].r;) add(++nowr);
for (;nowr>q[i].r;) del(nowr--);
ans[q[i].id]=sum[q[i].k];
}
for (i=1;i<=m;++i) write(ans[i]),pl;
}