线段树优化建图求卡空间
查看原帖
线段树优化建图求卡空间
1088663
zzzyyyyhhhhh楼主2024/10/11 19:05
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+100;
int f[N],tot,root;
struct vectorr
{
	signed *p;
	signed siz,maxsiz;
	vectorr()
	{
		maxsiz=0;
	}
	inline void nnew()
	{
		signed *p1=p;
		maxsiz*=1.1;
		maxsiz++;
		p=new signed[maxsiz];
		memcpy(p,p1,siz<<2);
		delete p1;
	}
	inline void push_back(signed x)
	{
		if(siz>=maxsiz-1)
		{
			nnew();
		}
		p[siz++]=x;
	}
	inline signed& operator[](signed x)
	{
		if(x>=siz)return siz;
		return p[x];
	}
	inline signed* begin()
	{
		return p;
	}
	inline signed* end()
	{
		return p+siz;
	}
	inline void era()
	{
		if(siz==0)return;
		siz--;
	}
	void ok()
	{
		signed *p1=p;
		maxsiz=siz;
		p=new signed[maxsiz];
		memcpy(p,p1,siz<<2);
		delete p1;
	}
};
vectorr a[(int)1e5+100];
vectorr tmp;
int tr[N][2];
#define ll (tr[x][0])
#define rr (tr[x][1])
#define mid ((l+r)>>1)
inline void build(int l,int r,int x)
{
	if(l==r)
	{
		ll=rr=l;
		return;
	}
	ll=++tot;
	rr=++tot;
	build(l,mid,ll);
	build(mid+1,r,rr);
}
int l1,r1,lss;
void add(int l,int r,int x)
{
	if(l>=l1&&r<=r1)
	{
		a[lss].push_back(x);
		return;
	}
	if(l1<=mid)add(l,mid,ll);
	if(r1>mid)add(mid+1,r,rr);
}
#undef mid
int find(int x)
{
	if(f[x]!=x)return f[x]=find(f[x]);
	return f[x];
}
void dfs(int x)
{
	if(x<root)
	{
		for(auto i:a[x])
		{
			if(find(i)==find(x))continue;
			f[find(i)]=find(x);
			dfs(i);
		}
	}
	else
	{
		if(find(tr[x][0])!=find(x))
		{
			f[find(tr[x][0])]=find(x);
			dfs(tr[x][0]);
		}
		if(find(tr[x][1])!=find(x))
		{
			f[find(tr[x][1])]=find(x);
			dfs(tr[x][1]);
		}
	}
}
vectorr v;
signed main()
{
	int n,m,x,y;
	cin>>n>>m;
	root=tot=n+1;
	build(1,n,root);
	for(int i=1;i<=tot;i++)f[i]=i;
	vectorr *b=new vectorr[(int)1e5+100];
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		b[x].push_back(y);
		b[y].push_back(x);
	}
	for(int i=1;i<=n;i++)sort(b[i].begin(),b[i].end());
	int ls=1;
	for(int i=1;i<=n;i++)
	{
		ls=1;
		for(auto j:b[i])
		{
			if(ls<j)
			{
				l1=ls,r1=j-1,lss=i;
				add(1,n,root);
			}
			ls=j+1;
		}
	}
	delete b;
	for(int i=1;i<=n;i++)
	{
		if(f[i]==i)
		{
			dfs(i);
		}
	}
	int cnt[(int)1e5+100];
	for(int i=1;i<=n;i++)
	{
		cnt[find(i)]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(cnt[i])v.push_back(cnt[i]);
	}
	cout<<v.siz<<'\n';
	sort(v.begin(),v.end());
	for(auto i:v)cout<<i<<' ';
}
2024/10/11 19:05
加载中...