树上莫队求调
查看原帖
树上莫队求调
1061320
Isharmla楼主2023/8/22 09:50

rt.

// Problem: COT2 - Count on a tree II
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/SP10707
// Memory Limit: 1 MB
// Time Limit: 1210 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define F(i,a,b) for(int i=a;i<=b;i++)
const int Maxn = 5e5 + 5;

int n, m, head[Maxn], nxt[Maxn], to[Maxn], tot, s[Maxn], t[Maxn], a[Maxn], u, v, idx,ans,Ans[Maxn];

int d, top[Maxn], id[Maxn], dep[Maxn], f[Maxn], son[Maxn], siz[Maxn],his[Maxn];

int vis[Maxn],tt;

map<int, int> ma;

inline int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f*=-1;
		c=getchar();
	}
	while(c<='9'&&c>='0'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
	return x*f;
}

inline void AddEdge(int u, int v) {
	to[++tot] = v;
	nxt[tot] = head[u];
	head[u] = tot;
}

void dfs1(int u) {
	siz[u] = 1;
	s[u]=++idx;
	his[idx]=u;
	dep[u] = dep[f[u]] + 1;
	for (int i = head[u]; i; i = nxt[i]) {
		if (to[i] == f[u]) continue;
		f[to[i]] = u;
		dfs1(to[i]);
		siz[u] += siz[to[i]];
		if ((!son[u]) || siz[son[u]] < siz[to[i]]) son[u] = to[i];
	}
	t[u]=++idx;
	his[idx]=u;
	return ;
}
void dfs2(int u, int v) {
	top[u] = v;
	if (!son[u]) return;
	dfs2(son[u], v);
	for (int i = head[u]; i; i = nxt[i]) {
		if (to[i] == f[u] || to[i] == son[u]) continue;
		dfs2(to[i], to[i]);
	}
	return;
}
inline int LCA(int u, int v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		u = f[top[u]];
	}
	return u;
}

struct node{
	int l,r,lca,id;
}q[Maxn];
	
int len;

inline bool cmp(node a,node b){
	if(a.l/len==b.l/len) return a.r<b.r;
	else return a.l<b.l;
}

inline void Add(int u){
	vis[a[his[u]]]++;
	ans+=(vis[a[his[u]]]==1);
}

inline void Del(int u){
	vis[a[his[u]]]--;
	ans-=(vis[a[his[u]]]==0);
}

signed main() {
	n=read(),m=read();
	F(i, 1, n) 
	{
		a[i]=read();
		if(ma[a[i]]==0) ma[a[i]]=(++tt),a[i]=tt;
		else a[i]=ma[a[i]];
	}
	F(i, 1, n - 1) {
		u=read(),v=read();
		AddEdge(u, v);
		AddEdge(v, u);
	}
	dfs1(1);
	dfs2(1, 1);
	F(i,1,m){
		cin>>q[i].l>>q[i].r;
		if(s[q[i].l]>s[q[i].r]) swap(q[i].l,q[i].r);
		int lca=LCA(q[i].l,q[i].r);
		if(lca==q[i].l) q[i].lca=0,q[i].l=s[q[i].l],q[i].r=s[q[i].r];
		else q[i].lca=lca,q[i].l=t[q[i].l],q[i].r=s[q[i].r];
		q[i].id=i;
	}
	len=sqrt(2*n);
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	F(i,1,m){
		while(l<q[i].l) Del(l++);
		while(r<q[i].r) Add(++r); 
		while(l>q[i].l) Add(--l);
		while(r>q[i].r) Del(r--);
		
		if(q[i].lca) Add(s[q[i].lca]);
		Ans[q[i].id]=ans;
		if(q[i].lca) Del(s[q[i].lca]);
	}
	F(i,1,m) cout<<Ans[i]<<endl;
	return 0;
}
2023/8/22 09:50
加载中...