树上莫队wa求助
查看原帖
树上莫队wa求助
289304
HAuCl4楼主2023/4/9 20:49

RT,感觉无肉眼可见的错

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=80005;
int n,m;
int hd[N],nxt[N],to[N],tot;
void link(int x,int y){
	to[++tot]=y;
	nxt[tot]=hd[x];
	hd[x]=tot;
	to[++tot]=x;
	nxt[tot]=hd[y];
	hd[y]=tot;
}
int c[N],t[N],nz;
void lisanhua(){
	memcpy(t,c,sizeof(c));
	sort(t+1,t+n+1);
	nz=unique(t+1,t+n+1)-t-1;
	for(int i=1;i<=n;i++)	
		c[i]=lower_bound(t+1,t+nz+1,c[i])-t;
}
int fa[N],sz[N],dep[N],son[N];
void dfs1(int u,int f,int depth)
{
	sz[u]=1; fa[u]=f; dep[u]=depth;
	for(int i=hd[u];i;i=nxt[i])
	{
		int v=to[i];
		if(v==f) continue;
		dfs1(v,u,depth+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
int top[N];
int st[N],ed[N],en=0;
int olx[N];
void dfs2(int u,int t)
{
	top[u]=t;
	++en; st[u]=en; olx[en]=u;
	if(!son[u]) 
	{
		++en; ed[u]=en; olx[en]=u;
		return;	
	}
	dfs2(son[u],t);
	for(int i=hd[u];i;i=nxt[i])
	{
		int v=to[i];
		if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
	}
	++en; ed[u]=en; olx[en]=u;
}
int lca(int x,int y)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	return dep[x]<dep[y]?x:y;
}

int belong[N];
struct cmd{
	int l,r,lca,id;
	bool operator < (const cmd& p) const{
		return belong[l]!=belong[p.l]?belong[l]<belong[p.l]:((belong[l]&1)?r<p.r : r>p.r);
	}
}T[100005];
int cnt[N],ret=0,ans[N];
bool vis[N];
void add(int x)
{
	if(!cnt[c[x]]) ret++;
	++cnt[c[x]];
}
void del(int x)
{
	--cnt[c[x]];
	if(!cnt[c[x]]) ret--;
}
void work(int x)
{
	vis[x]?del(x):add(x);
	vis[x]^=1;
}
int main()
{
	scanf("%d%d",&n,&m);
	int B=1000; 
	for(int i=1;i<=2*n;i++) belong[i]=(i-1)/B+1;
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	lisanhua();
	for(int i=1,ta,tb;i<n;i++)
	{
		scanf("%d%d",&ta,&tb);
		link(ta,tb);
	}
	dfs1(1,0,1);
	dfs2(1,1);
	for(int i=1,x,y,l;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		if(st[x]>st[y]) swap(x,y);
		l=lca(x,y);
		if(x==l) T[i]=cmd{st[x],st[y],0,i};
		else T[i]=cmd{ed[x],st[y],l,i};
	}
	sort(T+1,T+m+1);
	int L=1,R=0; 
	for(int i=1;i<=m;i++)
	{
		while(L>T[i].l) work(olx[--L]);
		while(R<T[i].r) work(olx[++R]);
		while(L<T[i].l) work(olx[L++]);
		while(R>T[i].r) work(olx[R--]);
		if(T[i].lca) work(T[i].lca);
		ans[T[i].id]=ret;
		if(T[i].lca) work(T[i].lca);
	}
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
	return 0;
}
2023/4/9 20:49
加载中...