社区讨论
左偏树求条玄关
P3377【模板】可并堆 1参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mkqw7fh6
- 此快照首次捕获于
- 2026/01/23 21:04 4 周前
- 此快照最后确认于
- 2026/01/24 12:20 4 周前
CPP
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=1e5+10;
struct node
{
int data,id;
int lc=-1,rc=-1;
}tree[maxn];
int n,m;
bool operator<(const node& a,const node& b)
{
if(a.data==b.data)
{
return a.id<b.id;
}
return a.data<b.data;
}
int fa[maxn];
int tx[maxn];
int ds[maxn];
bool is_del[maxn];
int merge(int,int);
int finf(int x)
{
if(fa[x]==x)return x;
return fa[x]=finf(fa[x]);
}
bool add(int x,int y)
{
if(is_del[x]||is_del[y])
{
return 0;
}
x=tx[x];
y=tx[y];
x=finf(x);
y=finf(y);
if(x==y)
{
return 0;
}
int t=merge(x,y);//if(x<0||y<0||t<0)throw"";
fa[x+y-t]=t;
}
int merge(int x,int y)//x,y为根
{
if(tree[y]<tree[x])
{
swap(x,y);
}
if(tree[x].lc==-1)
{
tree[x].lc=y;
ds[x]=1;
return x;
}
if(tree[x].rc==-1)
{
tree[x].rc=y;
}
else
{
tree[x].rc=merge(tree[x].rc,y);
}
if(ds[tree[x].lc]<ds[tree[x].rc])
{
swap(tree[x].lc,tree[x].rc);
}
ds[x]=ds[tree[x].rc]+1;
return x;
}
pair<bool,int> del(int p)
{
if(is_del[p])
{
return make_pair(false,0);
}
p=tx[p];
p=finf(p);
is_del[tree[p].id]=1;
int yy=tree[p].data;
int x=tree[p].lc,y=tree[p].rc;
int t;
if(y!=-1)
{
t=merge(x,y);//if(x<0||y<0||t<0)throw"";
}
else if(x!=-1)
{
t=y;
}
else
{
return make_pair(true,yy);
}
swap(tree[t],tree[p]);
tx[tree[p].id]=p;
return make_pair(true,yy);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
fa[i]=tx[i]=i;
is_del[i]=0;
ds[i]=1;
scanf("%d",&tree[i].data);
tree[i].id=i;
}
while(m--)
{
int op,x,y;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&x,&y);
add(x,y);
}
else
{
scanf("%d",&x);
pair<bool,int> pr=del(x);
if(!pr.first)
{
printf("%d\n",-1);
}
else
{
printf("%d\n",pr.second);
}
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...