启发式合并而已啦,,

调试时发现的错误点: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. C#语句

    C#控制语句 控制语句: goto语句 If语句 do while循环  for循环  while循环 switch语句 三元运算符   <test?><resultIfTrue&g ...

  2. 给深度学习入门者的Python快速教程 - numpy和Matplotlib篇

    始终无法有效把word排版好的粘贴过来,排版更佳版本请见知乎文章: https://zhuanlan.zhihu.com/p/24309547 实在搞不定博客园的排版,排版更佳的版本在: 给深度学习入 ...

  3. HDU 5130 Signal Interference --计算几何,多边形与圆的交面积

    题意: 求所有满足PB <= k*PA 的P所在区域与多边形的交面积. 解法: 2014广州赛区的银牌题,当时竟然没发现是圆,然后就没做出来,然后就gg了. 圆的一般式方程: 设A(x1,y1) ...

  4. UVa10820 Send a Table[欧拉函数]

    Send a TableInput: Standard Input Output: Standard Output When participating in programming contests ...

  5. POJ3636Nested Dolls[DP LIS]

    Nested Dolls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8323   Accepted: 2262 Desc ...

  6. poj 2481

    Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16163   Accepted: 5380 Description ...

  7. 弹性返回顶部JS代码

    弹性返回顶部JS代码 弹性返回顶部JS代码点击下载

  8. Ant 命令行编译Android项目

    首先把android sdk下的tools目录加到系统path环境变量里, 要么就得直接指定android.bat的绝对路径 对于一个新项目, 可以用这个命令创建需要的ant编译环境(可以看到andr ...

  9. Centos5.8 iptables管理

    使用第三方提供的Centos5.8 vmx安装的虚拟机实例, 在安装Tomcat时发现启动后8080端口无法访问, 先检查是否selinux作了限制 查看selinux状态: sestatus 查看s ...

  10. 借个例子说明sed的模式空间,以及针对模式空间的N,P,D用法

    下面是我们要处理的文本:题目要求是把所有散列在不同行的同一个中括号中的数据集中在一起, 见下表就秒懂了吧 处理前的文本 处理后的文本 [123456][ASDEF][ABCD123WF][789ADC ...