洛谷.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;
}
------------------------------------------------------------------------------------------------------------------------
很久以前的奇怪但现在依旧成立的签名
attack is our red sun $$\color{red}{\boxed{\color{red}{attack\ is\ our\ red\ sun}}}$$ ------------------------------------------------------------------------------------------------------------------------
很久以前的奇怪但现在依旧成立的签名
attack is our red sun $$\color{red}{\boxed{\color{red}{attack\ is\ our\ red\ sun}}}$$ ------------------------------------------------------------------------------------------------------------------------