萌新求助简单复杂度均摊问题
查看原帖
萌新求助简单复杂度均摊问题
455490
Sharpsmile楼主2024/3/24 15:38

RT,树上莫队板子。写的树分块那种。

哇了。大佬九敏qwq。

#include<bits/stdc++.h>
using namespace std;
//#define int long long
int n,q,a[40300],c[40030],b[40300];
vector<int>g[40030];
int dfn[40030],bel[40030],fa[40030],dep[40030];
struct ask{
	int l,r,id;
};
vector<ask>A;
stack<int>S;
const int SIZ=150;
int cnt,tk;
int res=0;
bool IN[40030];
int ANS[100030];
inline void ins(int x){if(!c[x])res++;c[x]++;}
inline void del(int x){c[x]--;if(!c[x])res--;}
inline void rev(int x){if(IN[x])del(a[x]);else ins(a[x]);IN[x]^=1;}
inline void REV(int u,int v){
	if(u==v)return ;
	while(u!=v){
		if(dep[u]<dep[v])swap(u,v);
		rev(u);
		u=fa[u]; 
	}
	if(!IN[u])rev(u);
}
inline void dfs(int u){
	S.push(u);
	dfn[u]=++tk,dep[u]=dep[fa[u]]+1;
	int pre=S.size();
	for(int v:g[u])
		if(v!=fa[u]){
			fa[v]=u;
			dfs(v);
			if(S.size()-pre>=SIZ){
				++cnt;
				while(S.top()!=u)bel[S.top()]=cnt,S.pop();
			}
		}
}
inline bool cmp(ask x,ask y){
	return bel[x.l]==bel[y.l]?dfn[x.r]<dfn[y.r]:bel[x.l]<bel[y.l];
}
signed main(){
	ios::sync_with_stdio(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
	sort(b+1,b+n+1);
	auto tmp = unique(b+1,b+n+1);
	for(int i=1;i<=n;i++)
	a[i]=lower_bound(b+1,tmp,a[i])-b;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1);
	while(!S.empty())
	bel[S.top()]=cnt,S.pop();
	for(int i=1;i<=q;i++){
		int u,v;
		cin>>u>>v;
		if(dfn[u]>dfn[v])swap(u,v);
		if(u!=v)A.push_back({u,v,i});
		else ANS[i]=1;		
	}
	sort(A.begin(),A.end(),cmp);
	int U=1,V=1;
	rev(1);
	for(ask P:A){
		REV(U,P.l),U=P.l;
		REV(V,P.r),V=P.r;
		ANS[P.id]=res;
	}
	for(int i=1;i<=q;i++)
	cout<<ANS[i]<<endl;
	
	return 0;
} 
2024/3/24 15:38
加载中...