【算法】可并堆(左偏树)

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
int l[maxn],r[maxn],fa[maxn],d[maxn],a[maxn],n,m;
bool die[maxn];//0生1死
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);}
int merge(int x,int y)//返回x和y合并后子树的根
{
if(!x)return y;
if(!y)return x;//遇到一边为空节点则把另一边剩余的子树整颗接上去(返回)
if(a[x]>a[y])swap(x,y);//将根节点更小的树放在左边
r[x]=merge(r[x],y);//递归合并左树右孩子和右树
if(d[l[x]]<d[r[x]])swap(l[x],r[x]);//维护左偏性质
d[x]=d[r[x]]+;//更新节点距离
return x;//返回新树根
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=n;i++)fa[i]=i;
d[]=-;//因为后面的空节点都表示为0,因此会多次调用0。
scanf("%d",&m);
for(int i=;i<=m;i++)
{
char c=getchar();
while(c!='M'&&c!='K')c=getchar();
if(c=='M')
{
int x,y;
scanf("%d%d",&x,&y);
if(die[x]||die[y])continue;
int p=find(x),q=find(y);
if(p!=q)
{
int t=merge(p,q);//t是新根,可能是fa[x]或fa[y]
fa[p]=fa[q]=t;//p,q的父亲变为新根,其他点父亲均不变
}
}
else
{
int x;
scanf("%d",&x);
if(die[x]){printf("0\n");continue;}
int p=find(x);die[p]=;
printf("%d\n",a[p]);
fa[p]=merge(l[p],r[p]);//返回新根(l[p]或r[p]),令原根的父亲为新根,由于并查集,不需要再修改
fa[fa[p]]=fa[p];//注意改变新根的父亲
//为什么不能直接加个if判断新根左右然后修改左右父亲啊?改完交了RE,存疑……
}
}
return ;
}

另有蒟蒻WA的代码,错误已标注。

WA Code >_<

最新文章

  1. Mac上搭建Nginx + rtmp
  2. chrome使用技巧(看了定不让你失望)
  3. mysql:SQL语句操作数据库中表和字段的COMMENT值
  4. Excel计算一列的和sum(A:A)
  5. magic_quotes_gpc、mysql_real_escape_string、addslashes的区别及用法
  6. Eclipse设置分级折叠显示项目工程路径
  7. Python 2.X-关于函数返回的数值类型
  8. Apache 开启压缩传输
  9. [CF52C]Circular RMQ【线段树】
  10. 010-Python-socket编程
  11. 影响 POST 请求文件上传失败的几个环节的配置(php + nginx)
  12. Python 处理 CSV/EXCEL 表格文件
  13. vs2010密钥
  14. hdu3613
  15. spring JdbcTemplate批量插入以及单个插入时获取id
  16. maven依赖jar包时版本冲突的解决
  17. 洛谷P2676 超级书架 题解
  18. opencv 图像增强
  19. VC++ 获取鼠标状态,获取鼠标弹起消息
  20. ArcEngnine中IHookHelper的用法

热门文章

  1. HDU 2117 Just a Numble
  2. LR脚本编写时的几个小技巧
  3. cacti 安装perl 和XML::Simple
  4. svmtrain输入参数介绍【转】
  5. Delphi SQL语句字符串拼接
  6. java 写入int型时会自动转换成字符
  7. uva1086 The Ministers&#39; Major Mess
  8. openstack之Glance介绍
  9. BZOJ4860 Beijing2017树的难题(点分治+单调队列)
  10. SPFA判負環