树上莫队求调
查看原帖
树上莫队求调
685183
LightSpot楼主2024/4/13 17:27
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int n , m , tmpans;
long long col[MAXN] , tmp[MAXN];
int ord[MAXN] , deep[MAXN] , fa[MAXN][17] , cnt[MAXN] , pos_ord[MAXN][2] , l , bl;
bool vst[MAXN];
vector <int> a[MAXN];
struct ask
{
	int l , r;
	int id;
	int lca_id;
};
ask q[100010];
int ans[100010];
bool cmp(ask x , ask y)
{
	if(x.l / bl != y.l / bl) return x.l / bl < y.l / bl;
	return ((x.l / bl) & 1) ? x.r < y.r : x.r > y.r;
}
void dfs(int x , int fno)
{
	fa[x][0] = fno;
	deep[x] = deep[fno] + 1;
	for(int i = 1 ; i <= 16 ; i++) fa[x][i] = fa[fa[x][i - 1]][i - 1];
	ord[++l] = x;
	pos_ord[x][0] = l;
	for(auto p : a[x]) if(p != fno) dfs(p , x);
	ord[++l] = x;
	pos_ord[x][1] = l;
	return;
}
int LCA(int x , int y)
{
	if(deep[x] != deep[y])
	{
		if(deep[x] < deep[y]) swap(x , y);
		for(int i = log2(deep[x] - deep[y]) ; i >= 0 ; i--)
		{
			if(fa[x][i] == 0) continue;
			x = fa[x][i];
		}
	}
	if(x == y) return x;
	for(int i = 16 ; i >= 0 ; i--)
	{
    	if(fa[x][i] != fa[y][i])
		{
    		x = fa[x][i];
    		y = fa[y][i];
    	}
	}
	return fa[x][0];
}
void upd(int x)
{
	vst[x] ^= 1; 
	if(!vst[x] && (--cnt[col[x]]) == 0) tmpans--;
	if(vst[x] && (cnt[col[x]]++) == 0) tmpans++;
}
int main()
{
	cin >> n >> m;
	bl = sqrt(n);
	for(int i = 1 ; i <= n ; i++)
	{
		scanf("%lld" , &col[i]);
		tmp[i] = col[i];
	}
	sort(tmp + 1, tmp + 1 + n);
	int len = unique(tmp + 1, tmp + n + 1) - (tmp + 1);
	for(int i = 1 ; i <= n ; i++) col[i] = lower_bound(tmp + 1 , tmp + len + 1 , col[i]) - tmp;
	for(int i = 1 ; i < n ; i++)
	{
		int u , v;
		scanf("%d%d" , &u , &v);
		a[u].push_back(v);
		a[v].push_back(u);
	}
	dfs(1 , 0);
	for(int i = 1 ; i <= m ; i++)
	{
		q[i].id = i;
		int u , v;
		scanf("%d%d" , &u , &v);
		int lca = LCA(u , v);
		if(deep[u] > deep[v]) swap(u , v);
		q[i] = {lca == l ? pos_ord[u][0] : pos_ord[u][1] , pos_ord[v][0] , i , lca};
	}
	sort(q + 1 , q + m + 1 , cmp);
	int l = 1 , r = 0;
	for(int i = 1 ; i <= m ; i++)
	{
		int ql = q[i].l , qr = q[i].r;
		while(l < ql) upd(ord[l++]);
		while(l > ql) upd(ord[--l]);
		while(r < qr) upd(ord[++r]);
		while(r > qr) upd(ord[r--]);
		if(q[i].lca_id) upd(q[i].lca_id);
		ans[q[i].id] = tmpans;
		if(q[i].lca_id) upd(q[i].lca_id);
	}
	for(int i = 1 ; i <= m ; i++) printf("%d\n" , ans[i]);
	return 0;
}
2024/4/13 17:27
加载中...