链接
题解
用dsu on tree艹过去了…
这题也可以莫队
代码(dsu on tree)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 100010
#define maxe 200010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int read(ll x=0)
{
int c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
struct Graph
{
int etot, head[maxn], to[maxe], next[maxe], w[maxe];
void clear(int N)
{
for(int i=1;i<=N;i++)head[i]=0;
etot=0;
}
void adde(int a, int b, int c=0){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
}G;
struct ShuLianPouFen
{
int size[maxn], top[maxn], tid[maxn], tim, untid[maxn], deep[maxn], son[maxn], fa[maxn];
void dfs1(Graph &G, int pos)
{
int p, v;
size[pos]=1;
for(p=G.head[pos];p;p=G.next[p])
{
if((v=G.to[p])==fa[pos])continue;
fa[v]=pos;
deep[v]=deep[pos]+1;
dfs1(G,v);
if(size[v]>size[son[pos]])son[pos]=v;
size[pos]+=size[v];
}
}
void dfs2(Graph &G, int pos, int tp)
{
int p, v;
top[pos]=tp;
tid[pos]=++tim;
untid[tid[pos]]=pos;
if(son[pos])dfs2(G,son[pos],tp);
for(p=G.head[pos];p;p=G.next[p])
if((v=G.to[p])!=fa[pos] and v!=son[pos])dfs2(G,v,v);
}
void run(Graph &G, int root)
{
tim=0;
deep[root]=1;
dfs1(G,root);
dfs2(G,root,root);
}
}sp;
int n, m, k[maxn], ans[maxn], cnt[maxn], c[maxn], forb, tmp[maxn];
vector<int> qlis[maxn];
void upd(int c, int opt)
{
if(opt==1)
{
cnt[c]++;
tmp[cnt[c]]++;
}
else
{
tmp[cnt[c]]--;
cnt[c]--;
}
}
void force(int pos, int pre, int opt)
{
upd(c[pos],opt);
for(auto p=G.head[pos];p;p=G.next[p])
if(G.to[p]!=pre and G.to[p]!=forb)force(G.to[p],pos,opt);
}
void dfs(int pos, int pre, int H)
{
for(auto p=G.head[pos];p;p=G.next[p])
if(G.to[p]!=pre and G.to[p]!=sp.son[pos])
dfs(G.to[p],pos,0);
if(sp.son[pos])dfs(sp.son[pos],pos,1);
forb=sp.son[pos];
force(pos,pre,+1);
for(auto q:qlis[pos])ans[q]=tmp[k[q]];
forb=0;
if(H==0)force(pos,pre,-1);
}
int main()
{
int i, u, v;
n=read(), m=read();
rep(i,n)c[i]=read();
rep(i,n-1)
{
u=read(), v=read();
G.adde(u,v), G.adde(v,u);
}
rep(i,m)
{
v=read(), k[i]=read();
qlis[v].emb(i);
}
sp.run(G,1);
dfs(1,0,0);
rep(i,m)printf("%d\n",ans[i]);
return 0;
}
代码(莫队)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 100010
#define maxe 200010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
struct Graph
{
int etot, head[maxn], to[maxe], next[maxe], w[maxe];
void clear(int N)
{
for(int i=1;i<=N;i++)head[i]=0;
etot=0;
}
void adde(int a, int b, int c=0){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
}G;
ll ltid[maxn], rtid[maxn], tim, tmp[maxn];
ll n, m, k[maxn], ans[maxn], cnt[maxn], c[maxn], l[maxn], r[maxn], id[maxn], col[maxn], S=316;
void dfs(ll pos, ll pre)
{
ltid[pos]=++tim;
col[tim]=c[pos];
for(auto p=G.head[pos];p;p=G.next[p])
if(G.to[p]!=pre)
dfs(G.to[p],pos);
rtid[pos]=tim;
}
void upd(ll x, ll v)
{
if(v==1)
{
cnt[col[x]]++;
tmp[cnt[col[x]]]++;
}
else
{
tmp[cnt[col[x]]]--;
cnt[col[x]]--;
}
}
int main()
{
ll i, u, v;
n=read(), m=read();
rep(i,n)c[i]=read();
rep(i,n-1)
{
u=read(), v=read();
G.adde(u,v), G.adde(v,u);
}
dfs(1,0);
rep(i,m)
{
v=read(), k[i]=read();
l[i]=ltid[v], r[i]=rtid[v];
id[i]=i;
}
sort(id+1,id+m+1,[](ll a, ll b){return l[a]/S==l[b]/S ? r[a]<r[b] : l[a]/S<l[b]/S; });
ll L=1, R=0;
rep(i,m)
{
for(;L>l[id[i]];L--)upd(L-1,+1);
for(;R<r[id[i]];R++)upd(R+1,+1);
for(;L<l[id[i]];L++)upd(L,-1);
for(;R>r[id[i]];R--)upd(R,-1);
ans[id[i]]=tmp[k[id[i]]];
}
rep(i,m)printf("%lld\n",ans[i]);
return 0;
}