博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

洛谷.3377.[模板]左偏树(可并堆)

题目链接
左偏堆学习 推荐

#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() (SS==TT &&(TT=(SS=IN)+fread(IN,1,1<<15,stdin),SS==TT)?EOF:*SS++)
const int N=1e5+7,DEL=-1<<30;

int n,m,val[N],son[N][2],dis[N],fa[N];//id[N]这个数组完全用不到,比较编号直接比较AB即可 
//long long val[N];//int就够了
char IN[1<<15],*SS=IN,*TT=IN;
//bool del[N];//也不需要,改变val值即可 

inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
	for(;isdigit(c);now=now*10+c-'0',c=gc());
	return now*f;
}

int Merge(int A,int B)
{
	if(!A||!B) return A+B;
	if(val[A]>val[B]||(val[A]==val[B]&&A>B)) std::swap(A,B);
	son[A][1]=Merge(son[A][1],B);
	fa[son[A][1]]=A;
	if(dis[son[A][1]]>dis[son[A][0]]) std::swap(son[A][1],son[A][0]);
//	if(!son[A][1]) dis[A]=0;
//	else dis[A]=dis[son[A][1]]+1;
	dis[A]=dis[son[A][1]]+1;
	return A;
}
int Top(int p)
{
	while(fa[p]) p=fa[p];
	return p;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("3377.in","r",stdin);
	freopen("3377.out","w",stdout);
#endif

	dis[0]=-1;
	n=read(),m=read();
	for(int i=1;i<=n;++i) val[i]=read();//,fa[i]=i;
	int opt,x,y;
	while(m--)
	{
		opt=read(),x=read();
		if(opt==1)
		{
			y=read();
			if(val[x]==DEL||val[y]==DEL||x==y) continue;
			Merge(Top(x),Top(y));//,printf("%d:%d %d:%d\n",x,Top(x),y,Top(y));
		}
		else if(val[x]==DEL)
			puts("-1");
		else
		{
			y=Top(x);
			printf("%d\n",val[y]),
			val[y]=DEL;
			fa[son[y][0]]=fa[son[y][1]]=0;
			Merge(son[y][0],son[y][1]);//,printf("%d:%d %d:%d\n",x,Top(x),y,Top(y));
		}
	}

	return 0;
}

第二次(2018.4.2):怎么不如以前快了。。

#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define MAXIN 50000//这个到底需要多大啊QAQ 
const int N=1e5+5,DEL=-1<<30;

char IN[MAXIN],*SS=IN,*TT=IN;
namespace Leftist_Tree
{
	#define lson son[x][0]
	#define rson son[x][1]

	int fa[N],son[N][2],dis[N],val[N];
	int Merge(int x,int y)
	{
		if(!x||!y) return x^y;
		if(val[x]>val[y]||(val[x]==val[y]&&x>y)) std::swap(x,y);
		rson=Merge(rson,y), fa[rson]=x;
		if(dis[lson]<dis[rson]) std::swap(lson,rson);
		dis[x]=dis[rson]+1;
		return x;
	}
	inline int Top(int x){
		while(fa[x]) x=fa[x];
		return x;
	}
}
using namespace Leftist_Tree;

inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
	for(;isdigit(c);now=now*10+c-'0',c=gc());
	return now*f;
}

int main()
{
	dis[0]=-1;
	int n=read(),Q=read(),opt,x,y;
	for(int i=1; i<=n; ++i) val[i]=read();
	while(Q--)
	{
		opt=read(),x=read();
		if(opt==1)
		{
			y=read();
			if(val[x]==DEL||val[y]==DEL||x==y) continue;
			if((x=Top(x))!=(y=Top(y))) Merge(x,y);
		}
		else if(val[x]==DEL) puts("-1");
		else
		{
			printf("%d\n",val[x=Top(x)]),val[x]=DEL;
			fa[lson]=fa[rson]=0, Merge(lson,rson);//记得清空fa[]!
		}
	}
	return 0;
}
posted @ 2018-02-09 13:15  SovietPower  阅读(182)  评论(0编辑  收藏  举报