伪树上莫队求调,玄关。
查看原帖
伪树上莫队求调,玄关。
469487
wxw_zl楼主2024/10/24 11:53

在vjudge上提交的,wa了,记录

#include<bits/stdc++.h>
#define rise(i,l,r) for(int i=l;i<=r;i++)
#define fall(i,r,l) for(int i=r;i>=l;i--)
using namespace std;
const int maxn=2e5+10;
int n,m,sqn;
vector<int>g[maxn]; 
int f[maxn],idxf,fir[maxn],las[maxn];//用于记录欧拉序
int c[maxn],c1[maxn];
int fa[maxn][18],dep[maxn];
int block[maxn],ans1[maxn],ans;
int cnt[maxn];
struct prb{
	int l,r,lca,id;
	prb(int a,int b,int c){
		l=a;
		r=b;
		id=c;
	}
	bool operator <(const prb&a)const{
		if(block[l]^block[a.l])return block[l]<block[a.l];
		else return block[l]&1?r<a.r:r>a.r;
	}
};
vector<prb>ask;
int read(){
	int s=0,t=1;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-')t*=-1;
		c=getchar();
	}
	while(isdigit(c)){
		s=(s<<3)+(s<<1)+c-48;
		c=getchar();
	}
	return s*t;
}
void add(int x,int y){
	g[x].push_back(y);
}
void in(){
	n=read();m=read();
	rise(i,1,n)	c[i]=c1[i]=read();
	int u,v;
	rise(i,1,n-1){
		u=read();v=read();
		add(u,v);
		add(v,u);
	}
	rise(i,1,m){
		u=read();
		v=read();
		ask.push_back(prb(u,v,i));
	}
}
void unq(){
	sort(c1+1,c1+1+n);
	int len=unique(c1+1,c1+1+n)-c1-1;
	rise(i,1,n)	c[i]=lower_bound(c1+1,c1+1+len,c[i])-c1;
//	cout<<len<<endl;
//	rise(i,1,n)cout<<c[i]<<" ";
//	cout<<endl; 
}
void dfs(int x){
	fir[x]=++idxf;
	f[idxf]=x;
	dep[x]=dep[fa[x][0]]+1;
	rise(i,0,g[x].size()-1){
		int v=g[x][i];
		if(v==fa[x][0])continue;
		fa[v][0]=x;
		rise(i,1,log2(dep[v]))fa[v][i-1]=fa[fa[v][i-1]][i-1]; 
		dfs(v);
	}
	las[x]=++idxf;
	f[idxf]=x;
}
int getlca(int a,int b){
	if(dep[a]<dep[b])swap(a,b);
	fall(i,17,0)
		if(dep[fa[a][i]]>=dep[b])a=fa[a][i];
	if(a==b)return a;
	fall(i,17,0){
		if(fa[a][i]!=fa[b][i]){
			a=fa[a][i];
			b=fa[b][i];
		}
	}	
	return fa[a][0];
}
void add(int p){//p 应为颜色 
	ans+= ++cnt[p]==1;
}
void del(int p){
	ans-= --cnt[p]==0;
}
void Mo(){
	int l=1,r=0;
	rise(i,1,m){
		int L=ask[i].l,R=ask[i].r,lca=ask[i].lca;
		while(L<l)add(c[f[--l]]);
		while(r<R)add(c[f[++r]]);
		while(L>l)del(c[f[l++]]);
		while(r>R)del(c[f[r--]]);
		ans1[ask[i].id]=ans+(cnt[lca]==0);
	}
} 
int main(){
	cnt[0]=1;
	ask.push_back(prb(0,0,0));
	in();
	unq();
	dfs(1);
	sqn=sqrt(idxf);
	rise(i,1,idxf)block[i]=(i-1)/sqn+1; 
	rise(i,1,m){
		if(fir[ask[i].l]>fir[ask[i].r])swap(ask[i].l,ask[i].r);
		ask[i].lca=getlca(ask[i].l,ask[i].r);
		if(ask[i].l==ask[i].lca){
		ask[i].l=fir[ask[i].l];
		ask[i].r=fir[ask[i].r];
		ask[i].lca=0;
		}
		else {
		ask[i].l=las[ask[i].l];
		ask[i].r=fir[ask[i].r];
		ask[i].lca=c[ask[i].lca];
		}
	}
	sort(ask.begin(),ask.end());
	Mo();
	rise(i,1,m)printf("%d\n",ans1[i]);
	return 0;
}
2024/10/24 11:53
加载中...