萌新求助树上莫队
查看原帖
萌新求助树上莫队
14274
(。’_‘。)楼主2022/2/26 13:44
#include <bits/stdc++.h> 
using namespace std;
int n,q,col[1000005],first[1000005],last[1000005],u,v;
int id,head[1000005],m,a[1000005],l,r;
int f[100005][30],dep[1000005],wzw[1000005],b[1000005];
int k[1000005],opt[1000005],cnt[1000005],ans1[1000005];
int ans;
struct edge{
	int next,tar;
}e[1000005];
void add_edge(int u,int v){
	id++;
	e[id].tar=v;
	e[id].next=head[u];
	head[u]=id;
	return;
}
void dfs(int u,int fa,int deep){
	m++;
	first[u]=m;
	a[m]=u;
	f[u][1]=fa;
	dep[u]=deep;
	wzw[u]=1;
	for (int i=2;(1<<i)<=deep;i++){
		f[u][i]=f[f[u][i-1]][i-1];
		wzw[u]=i;
	}
	for (int i=head[u];i;i=e[i].next){
		if (e[i].tar==fa) continue;
		dfs(e[i].tar,u,deep+1);
	}
	m++;
	last[u]=m;
	a[m]=u;
}
int lca(int x,int y){
	if (dep[x]<dep[y]) swap(x,y);
	int k=wzw[x];
	for (int i=k;i>=1;i--){
		if (dep[f[x][i]]>=dep[y]) x=f[x][i];
	}
	k=wzw[x];
	for (int i=k;i>=1;i--)
		if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	return f[x][1];
}
struct md{
	int l,r,tepan,id;
}mo[1000005];
bool cmp(md a,md b){
	return k[a.l]<k[b.l]||(k[a.l]==k[b.l]&&a.r<b.r);
}
bool cmp1(md a,md b){
	return a.id<b.id;
}
int main(){
	scanf("%d%d",&n,&q);
	for (int i=1;i<=n;i++){
		scanf("%d",&col[i]);
		b[i]=col[i];
	}
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n)-b-1;
	for (int i=1;i<=n;i++){
		col[i]=lower_bound(b+1,b+1+len,col[i])-b;
	}
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs(1,1,1);
	int s=pow(m,0.5);
	for (int i=1;i<=m;i++)
		k[i]=(i-1)/s+1; 
	for (int i=1;i<=q;i++){
		scanf("%d%d",&l,&r);
		if (first[l]>first[r]) swap(l,r);
		if (lca(l,r)==l){
			mo[i].l=first[l];
			mo[i].r=first[r];
		} else {
			mo[i].l=last[l];
			mo[i].r=first[r];
			mo[i].tepan=lca(l,r);
		}
		mo[i].id=i;
	}
	sort(mo+1,mo+1+q,cmp);
	l=1;r=0;
	for (int i=1;i<=q;i++){
		while (l>mo[i].l){
			l--;
			opt[a[l]]^=1;
			if (opt[a[l]]){
				cnt[col[a[l]]]++;
				if (cnt[col[a[l]]]==1) ans++;
			} else {
				cnt[col[a[l]]]--;
				if (!cnt[col[a[l]]]) ans--;
			}
		}
		while (r<mo[i].r){
			r++;
			opt[a[r]]^=1;
			if (opt[a[r]]){
				cnt[col[a[r]]]++;
				if (cnt[col[a[r]]]==1) ans++;
			} else {
				cnt[col[a[r]]]--;
				if (!cnt[col[a[r]]]) ans--;
			}
		}
		while (l<mo[i].l){
			opt[a[l]]^=1;
			if (opt[a[l]]){
				cnt[col[a[l]]]++;
				if (cnt[col[a[l]]]==1) ans++;
			} else {
				cnt[col[a[l]]]--;
				if (!cnt[col[a[l]]]) ans--;
			}
			l++;
		}
		while (r>mo[i].r){	
			opt[a[r]]^=1;
			if (opt[a[r]]){
				cnt[col[a[r]]]++;
				if (cnt[col[a[r]]]==1) ans++;
			} else {
				cnt[col[a[r]]]--;
				if (!cnt[col[a[r]]]) ans--;
			}
			r--;
		}
		if (mo[i].tepan) {
			if (!cnt[col[mo[i].tepan]]) ans1[mo[i].id]=ans+1; else
				ans1[mo[i].id]=ans;
		} else
		ans1[mo[i].id]=ans;
	}
	sort(mo+1,mo+1+q,cmp1);
	for (int i=1;i<=q;i++)
		printf("%d\n",ans1[i]);
	return 0;
}
2022/2/26 13:44
加载中...