启发式合并而已啦,,

调试时发现的错误点: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. POJ 1696 Space Ant --枚举,模拟,贪心,几何

    题意: 有很多点,从最右下角的点开始走起,初始方向水平向右,然后以后每步只能向左边走,问最多能走多少个点. 解法: 贪心的搞的话,肯定每次选左边的与它夹角最小的点,然后走过去. 然后就是相当于模拟地去 ...

  2. AC日记——将字符串中的小写字母换成大写字母 openjudge 1.7 13

    13:将字符串中的小写字母转换成大写字母 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个字符串,将其中所有的小写字母转换成大写字母. 输入 输入一行,包含一个字符串(长度不 ...

  3. Prefab Assist插件

    资料 Prefab文档: http://game.ceeger.com/Manual/Prefabs.html 基础:基于NGUI制作组件的Prefab 前言 在一个游戏的UI中,有一些通用的组件,比 ...

  4. UNITY3D单词学习 speed和velocity的区别

    在日常用语中,这两个词没有区别,可以通用. 而在物理学里,velocity 是一个矢量(vector quantity)表示起点与终点间直线距离的长度除以所用时间所得的量,并注明方向;而 speed ...

  5. VS的快捷键F12改成和ECLIPSE一样用ctrl+点击下载线

    安装resharper 插件即可 不过这个插件是收费的,可免费体验30天

  6. NODE.JS开发指南学习笔记

    1.Node.js是什么 Node.js是一个让JS运行在服务器端的开发平台,它可以作为服务器向用户提供服务.Node.js中的javascript只是Core javascript,或者说是ECMA ...

  7. [No00005D]如何高效利用GitHub

    原文地址:http://www.yangzhiping.com/tech/github.html 正是Github,让社会化编程成为现实.本文尝试谈谈GitHub的文化.技巧与影响. Q1:GitHu ...

  8. python魔法函数的一些疑问

    看了魔法函数,有一点疑问.1中需要用self.word才能执行,而2直接用self就可以执行.而1中Word继承了int基本类型,但在__new__时并没有什么卵用.当用 Word(“123”)来实例 ...

  9. js左右滚动幻灯

    js左右滚动幻灯 点击下载

  10. Html5 Egret游戏开发 成语大挑战(八)一般性二级页面处理

    在游戏中,我们一般会有各种各样的二级页面,比如游戏暂停界面或者游戏结束界面,这些界面组成了对玩家交互主要手段,在游戏开发中,对于这些界面的coding组织是非常有学问的,如果倒退到十年前,游戏开发的老 ...