标签:lag printf str turn amp update print als 复杂
树上数颜色,因为是查询子树,所以用 \(dfn\) 序将树上问题转化为序列问题,然后就是裸的莫队数颜色了。
统计答案时还需注意一些细节问题,实现就看代码。
时间复杂度为 \(O(n\sqrt{n})\)。
\(code:\)
#include<bits/stdc++.h>
#define maxn 200010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,block,l=1,r,tot;
int a[maxn],c[maxn],cnt[maxn],ans[maxn],num[maxn];
struct query
{
int l,r,id,pos,ask;
}q[maxn];
bool cmp(query a,query b)
{
return a.pos==b.pos?(a.pos&1?a.r<b.r:a.r>b.r):a.pos<b.pos;
}
struct edge
{
int to,nxt;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
int dfn_cnt;
int siz[maxn],dfn[maxn];
void dfs(int x)
{
siz[x]=1;
dfn[x]=++dfn_cnt;
c[dfn_cnt]=a[x];
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(dfn[y]) continue;
dfs(y);
siz[x]+=siz[y];
}
}
void update(int x,int p)
{
x=c[x];
cnt[x]+=p;
if(~p) num[cnt[x]]++;
else num[cnt[x]+1]--;
}
int main()
{
read(n),read(m);
block=sqrt(n);
for(int i=1;i<=n;++i) read(a[i]);
for(int i=1;i<n;++i)
{
int a,b;
read(a),read(b);
add(a,b),add(b,a);
}
dfs(1);
for(int i=1;i<=m;++i)
{
int root;
read(root),read(q[i].ask);
q[i].l=dfn[root],q[i].r=dfn[root]+siz[root]-1;
q[i].id=i,q[i].pos=q[i].l/block;
}
sort(q+1,q+m+1,cmp);
for(int i=1;i<=m;++i)
{
int ql=q[i].l,qr=q[i].r,id=q[i].id,ask=q[i].ask;
while(l<ql) update(l++,-1);
while(r>qr) update(r--,-1);
while(l>ql) update(--l,1);
while(r<qr) update(++r,1);
ans[id]=num[ask];
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;
}
标签:lag printf str turn amp update print als 复杂
原文地址:https://www.cnblogs.com/lhm-/p/12229821.html