启发式合并而已啦,,

调试时发现的错误点:insert后没有splay,把要拆开的树的点插入另一个树时没有把ch[2]和fa设为null,找第k大时没有先减k,,,

都是常犯的错误,比赛时再这么粗心就得滚粗了

#include<cstdio>
#include<cstring>
#include<algorithm>
#define read(x) x=getint()
using namespace std;
inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
struct node *null;
struct node{
node();
node *fa,*ch[2];
int id,d,s;
bool pl() {return fa->ch[1]==this;}
void count() {s=ch[0]->s+ch[1]->s+1;}
void setc(node *r,bool c) {this->ch[c]=r; if (r!=null) r->fa=this;}
}*rt[100003],pool[100003];
node::node() {d=s=0;ch[0]=ch[1]=fa=null;}
int tot=0,n,m;
inline node *newnode(){
node *t=&pool[++tot];
t->ch[0]=t->ch[1]=t->fa=null;
return t;
}
inline void init() {null=&pool[0];null->s=null->d=0; null->ch[0]=null->ch[1]=null->fa=null;}
inline void rotate(node *r){
node *f=r->fa; bool c=r->pl();
if (f->fa!=null) f->fa->setc(r,f->pl());
else r->fa=null;
f->setc(r->ch[!c],c); r->setc(f,!c);
f->count();
}
inline void splay(node *r){
for(;r->fa!=null;rotate(r))
if(r->fa->fa!=null)rotate(r->fa->pl()==r->pl()?r->fa:r);
r->count();
}
inline void ins(node *r,node *k){
int num=k->d; bool c;
while (r!=null){
if (num<r->d) c=0; else c=1;
if (r->ch[c]==null) {r->setc(k,c); splay(k); return;} else r=r->ch[c];
}
}
inline node *fdr(node *r) {while (r->fa!=null) r=r->fa; return r;}
inline int QQ(node *r,int k){
if (r->s<k) return -1;
while (r!=null){
if (r->ch[0]->s>=k) r=r->ch[0];
else if (r->ch[0]->s+1>=k) return r->id;
else k-=r->ch[0]->s+1,r=r->ch[1];
}
}
inline void BB(node *r,node *t){
if (t==null) return;
BB(r,t->ch[0]); BB(r,t->ch[1]);
t->ch[0]=t->ch[1]=t->fa=null;
ins(r,t); splay(t);
}
int main(){
init();
read(n); read(m);
int x,y; char c; node *s,*t;
for(int i=1;i<=n;++i) {rt[i]=newnode(); read(rt[i]->d); rt[i]->s=1; rt[i]->id=i;}
for(int i=1;i<=m;++i) {
read(x); read(y);
if (x==0||y==0) continue;
s=fdr(rt[x]); t=fdr(rt[y]);
if (s==t) continue;
if (s->s<t->s) swap(s,t);
BB(s,t);
}
read(m);
while (m--){
c=getchar();
while ((c!='Q')&&(c!='B')) c=getchar();
read(x); read(y);
switch (c){
case 'Q':
printf("%d\n",QQ(fdr(rt[x]),y));
break;
case 'B':
s=fdr(rt[x]); t=fdr(rt[y]);
if (s==t) continue;
if (s->s<t->s) swap(s,t);
if (s!=t) BB(s,t);
break;
}
}
return 0;
}

PS:最后一组数据有一行是0 0,特判掉这个错误数据就行啦

【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并的更多相关文章

  1. BZOJ 2733 HNOI 2012 永无乡 平衡树启示式合并

    题目大意:有一些岛屿,一開始由一些无向边连接. 后来也有不断的无向边增加,每个岛屿有个一独一无二的重要度,问随意时刻的与一个岛屿联通的全部岛中重要度第k大的岛的编号是什么. 思路:首先连通性一定要用并 ...

  2. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  3. 【BZOJ-2733】永无乡 Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2048  Solved: 1078[Submit][Statu ...

  4. [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  5. 洛谷.3224.[HNOI2012]永无乡(Splay启发式合并)

    题目链接 查找排名为k的数用平衡树 合并时用启发式合并,把size小的树上的所有节点插入到size大的树中,每个节点最多需要O(logn)时间 并查集维护连通关系即可 O(nlogn*insert t ...

  6. 【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)

    题目: 洛谷3224 分析: 这题一看\(n\leq100000\)的范围就知道可以暴力地用\(O(nlogn)\)数据结构乱搞啊-- 每个联通块建一棵Splay树,查询就是Splay查询第k大的模板 ...

  7. HNOI 2012 永无乡

    codevs 1477 永无乡 http://codevs.cn/problem/1477/ 2012年湖南湖北省队选拔赛  时间限制: 1 s  空间限制: 128000 KB   题目描述 Des ...

  8. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

  9. 【bzoj2733】[HNOI2012]永无乡 Treap启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

随机推荐

  1. Mantis1.2.19 在Windows 平台上的安装配置详解

    安装环境: WindowsXP 32 Apache2.2.22+PHP5.4.39+MySQL5.5.28 一.简介 MantisBT是由PHP开发的.基于WEB的缺陷跟踪系统,并采用开源数据库MyS ...

  2. 方便!C++ builder快捷键大全

    Clipboard control (default) Ctrl+Ins Edit|Copy Shift+Del Edit|Cut Shift+Ins Edit|Paste Ctrl+C Edit|C ...

  3. [No000037]操作系统Operating Systems操作系统历史与硬件概况History of OS & Summaries!

    培根:读史使人明智 操作系统的简史 (1955-1965) 计算机非常昂贵,上古神机IBM7094 ,造价在250万美元以上 计算机使用原则:只专注于计算 批处理操作系统(Batch system) ...

  4. Eclipse cpp 开发 include路径

  5. eclipse 编译android程序 编译错误

    windows->show view -> problems, 这个窗口的内容即为 编译错误的内容.

  6. (转载)ORA-14452:试图创建,更改或删除正在使用的临时表中的索引

    因为表kol_xx_fin050_temp 为临时表,而且有其他session正在使用. 处理步骤: 1.先从 dba_objects / user_objects中查询到该表的object_id: ...

  7. PhpExcel中文帮助手册|PhpExcel使用方法

    下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...

  8. php常见问题

    1,新安装的lamp在打开php文件的时候出现access forbid问题,这个出现的原因是directory的路径权限问题,解决方法 将httpd.conf中的 <Directory /&g ...

  9. 纯手工打造漂亮的瀑布流,五大插件一个都不少Bootstrap+jQuery+Masonry+imagesLoaded+Lightbox!

    前两天写的文章<纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!>受到很多网友的喜爱,今天特别推出姊妹篇<纯手工打造漂亮的瀑 ...

  10. 别再迷信 zepto 了

    希望网上公开课的老师们不要再讲移动端网页用zepto了,坑了无数鸟啊 ~~~. 1.自己/公司/项目组所写和所积累(网上下的)的js函数都是以jQuery插件的写法来写的,如果要换到zepto上的话那 ...