HNOI2012 永无乡

题目链接:https://www.luogu.org/problemnew/show/P3224

splay启发式合并模板,小splay往大splay插,感性理解,一个点最多插logn次,插一次logn,n个点,nlognlogn~

#include
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
const int N = 2e5+10;
int n,m,a[N];
int fa[N],rt[N];
inline int getfa(int x){//连通性用并查集维护 
	return x^fa[x]?fa[x]=getfa(fa[x]):x;
}
struct Splay{
	int p[N],ch[N][2];
	int cnt,vl[N],idx[N],siz[N];
	#define Ls(x) ch[x][0]
	#define rs(x) ch[x][1]
	#define maintain(x) siz[x]=siz[Ls(x)]+siz[rs(x)]+1
	inline void rotate(int x){
		int f=p[x],gf=p[f],tp=rs(f)==x,son=ch[x][!tp];
		ch[p[son]=f][tp]=son,maintain(f);
		ch[p[f]=x][!tp]=f,maintain(x);
		ch[p[x]=gf][rs(gf)==f]=x;
	}
	inline void splay(int x,int goal,int &root){
		if(x==goal)return ;
		while(p[x]^goal){
			if((p[p[x]]^goal)&&((rs(p[p[x]])==p[x])==(rs(p[x])==x)))rotate(p[x]);
			rotate(x);
		}
		if(!goal)root=x;
	}
	inline void newnode(int x,int k,int Fa,int Idx){
		idx[x]=Idx,siz[x]=1,vl[x]=k,p[x]=Fa;
	}
	inline void insert(int &x,int k,int Fa,int Idx,int &root){
		if(!x)return newnode(x=++cnt,k,Fa,Idx),splay(x,0,root),void();
		insert(ch[x][vl[x]

 

你可能感兴趣的:(数据结构,splay)