莫队排序求条
  • 板块学术版
  • 楼主Green_Leaves
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/11/19 17:07
  • 上次更新2024/11/19 19:21:08
查看原帖
莫队排序求条
1375749
Green_Leaves楼主2024/11/19 17:07

rt,它在sort那里死递归了,我把比较函数改成直接比较l都可以过样例:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int color[40005],n,m,l_pos[40005],r_pos[40005],fa[40005],son[40005],tp[40005],dep[40005],len,tong[40005],ctong[40005],anss[100005],ans=0;
vector<int> edge[40005],oula;
struct node{
	int l,r,add=0,i;
	bool operator<(const node& b)const{
		int k1=l/len,k2=b.l/len;
		if(k1==k2)return r<b.r;
		else return k1<k2;
	}
}qs[100005];
int dfs1(int u,int f){
	oula.push_back(u);
	fa[u]=f;
	l_pos[u]=oula.size()-1;
	int siz=1,x,mxx=0;
	for(int i:edge[u]){
		if(i!=f){
			dep[i]=dep[u]+1;
			x=dfs1(i,u);
			siz+=x;
			if(x>mxx)son[u]=i;
			mxx=max(mxx,x);
		}
	}
	oula.push_back(u);
	r_pos[u]=oula.size()-1;
	return siz;
}
void dfs2(int u,int p){
	tp[u]=p;
	if(son[u])dfs2(son[u],p);
	for(int i:edge[u])if(i!=fa[u]&&i!=son[u])dfs2(i,i);
}
int LCA(int a,int b){
	while(tp[a]!=tp[b]){
		if(dep[tp[a]]<dep[tp[b]])b=fa[tp[b]];
		else a=fa[tp[a]];
	}
	return (dep[a]<dep[b]?a:b);
}
int main(){
	ios::sync_with_stdio(0);
	memset(tong,-1,sizeof(tong));
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>color[i];
	vector<int> v(color+1,color+1+n);
	sort(v.begin(),v.end());
	for(int i=1;i<=n;i++)color[i]=find(v.begin(),v.end(),color[i])-v.begin()+1;
	v.clear();
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=0;i<m;i++){
		int a,b,lca;
		cin>>a>>b;
		lca=LCA(a,b);
		if(lca==a||lca==b){
			qs[i].l=min(l_pos[a],l_pos[b]);
			qs[i].r=max(l_pos[a],l_pos[b]);
		}else{
			if(l_pos[a]<l_pos[b])qs[i].l=r_pos[a],qs[i].r=l_pos[b];
			else qs[i].l=r_pos[b],qs[i].r=l_pos[a];
			qs[i].add=lca;
		}
		qs[i].i=i;
	}cerr<<"a ok\n";
	sort(qs,qs+m);cerr<<"b ok\n";
	int l=1,r=0;
	for(int i=0;i<m;i++){
		while(l<qs[i].l){
			l++;
			if(ctong[color[oula[l]]]==0&&tong[oula[l]]==-1)ans++;
			if(ctong[color[oula[l]]]==1&&tong[oula[l]]==1)ans--;
			tong[oula[l]]=-tong[oula[l]];
			ctong[color[oula[l]]]+=tong[oula[l]];
		}
		while(r>qs[i].r){
			r--;
			if(ctong[color[oula[r]]]==0&&tong[oula[r]]==-1)ans++;
			if(ctong[color[oula[r]]]==1&&tong[oula[r]]==1)ans--;
			tong[oula[r]]=-tong[oula[r]];
			ctong[color[oula[r]]]+=tong[oula[r]];
		}
		while(l>qs[i].l){
			if(ctong[color[oula[l]]]==0&&tong[oula[l]]==-1)ans++;
			if(ctong[color[oula[l]]]==1&&tong[oula[l]]==1)ans--;
			tong[oula[l]]=-tong[oula[l]];
			ctong[color[oula[l]]]+=tong[oula[l]];
			l--;
		}
		while(r<qs[i].r){
			if(ctong[color[oula[r]]]==0&&tong[oula[r]]==-1)ans++;
			if(ctong[color[oula[r]]]==1&&tong[oula[r]]==1)ans--;
			tong[oula[r]]=-tong[oula[r]];
			ctong[color[oula[r]]]+=tong[oula[r]];
			r++;
		}
		if(qs[i].add&&ctong[color[i]]==0)anss[qs[i].i]=ans+1;
		else anss[qs[i].i]=ans;
	}
	for(int i=0;i<m;i++)cout<<anss[i]<<'\n';
}
2024/11/19 17:07
加载中...