树上莫队板子求调(WA on #1)
查看原帖
树上莫队板子求调(WA on #1)
779970
lunjiahao楼主2024/8/21 09:27
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=2e5+5;
int fa[N],dep[N],siz[N],hs[N];
int st[N],ed[N],dfn[N],tim;
vector<int> g[N];
void dfs1(int u,int fath)
{
	fa[u]=fath,dep[u]=dep[fath]+1;
	siz[u]=1,hs[u]=-1;
	st[u]=++tim,dfn[tim]=u;
	for(auto v:g[u])
	{
		if(v==fath) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(hs[u]==-1||siz[v]>siz[hs[u]]) hs[u]=v;
	}
	ed[u]=++tim,dfn[tim]=u;
}
int top[N];
void dfs2(int u,int t)
{
	top[u]=t;
	if(hs[u]!=-1) dfs2(hs[u],t);
	for(auto v:g[u])
		if(v!=fa[u]&&hs[u]!=v) dfs2(v,v);
}
int LCA(int u,int v)
{
	while(top[u]^top[v])
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	return v;
}
struct dat
{
	int l,r,id,lca;
}p[N];
int fk[N];
bool cmp(dat a,dat b)
{
	return fk[a.l]^fk[b.l]? a.l<b.l: fk[a.l]&1? a.r<b.r: a.r>b.r;
}
int cnt[N],vis[N],tot,a[N];
void add(int u)
{
	tot+=(++cnt[a[u]]==1);
}
void del(int u)
{
	tot-=(--cnt[a[u]]==0);
}
void calc(int u)
{
	if(vis[u]) del(u);
		else add(u);
	vis[u]^=1;
}
int n,Q,b[N],ans[N];
int main()
{
	scanf("%d%d",&n,&Q);
	int t=sqrt(n<<1);
	for(int i=1;i<=n;i++) scanf("%d",a+i),b[i]=a[i];
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+len,a[i])-b;
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v),g[v].pb(u);
	}
	dfs1(1,0),dfs2(1,1);
	for(int i=1;i<=n<<1;i++) fk[i]=(i-1)/t+1;
	for(int i=1;i<=Q;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		if(st[u]>st[v]) swap(u,v);
		int lca=LCA(u,v);
		if(lca==u) p[i]=(dat){st[u],st[v],i,0};
		else p[i]=(dat){ed[u],st[v],i,lca};
	}
	sort(p+1,p+1+Q,cmp);
	int L=1,R=0;
	for(int i=1;i<=Q;i++)
	{
		if(L>p[i].l) calc(dfn[--L]);
		if(R<p[i].r) calc(dfn[++R]);
		if(L<p[i].l) calc(dfn[L++]);
		if(R>p[i].r) calc(dfn[R--]);
		if(p[i].lca) calc(p[i].lca);
		ans[p[i].id]=tot;
		if(p[i].lca) calc(p[i].lca);
	}
	for(int i=1;i<=Q;i++) printf("%d\n",ans[i]);
	return 0;
}
2024/8/21 09:27
加载中...