2733: [HNOI2012]永无乡

题意:加边,询问一个连通块中k小值


终于写了一下splay启发式合并

本题直接splay上一个节点对应图上一个点就可以了

并查集维护连通性

合并的时候,把size小的树的所有节点插入到size大的中,每个点最多插入log次,复杂度\(O(nlogn*insert\ time)\)

然后主席说如果按照顺序插入,插入的复杂度均摊\(O(1)\),总的复杂度\(O(nlogn)\),随便中序遍历一下就有序了.貌似并没有更快

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define pa t[x].fa
const int N=1e5+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
} int n, m, val[N], x, y, Q; char s[5];
int fa[N];
inline int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
struct SplayTree{
struct meow{
int ch[2], fa, size, v;
}t[N];
int sz, root;
inline void ini() {
for(int i=1; i<=n; i++) t[i].v=val[i], t[i].size=1;
}
inline int wh(int x) {return t[pa].ch[1] == x;}
inline void update(int x) {t[x].size = t[lc].size + t[rc].size + 1;}
inline void rotate(int x) {
int f=t[x].fa, g=t[f].fa, c=wh(x);
if(g) t[g].ch[wh(f)]=x; t[x].fa=g;
t[f].ch[c] = t[x].ch[c^1]; t[t[f].ch[c]].fa=f;
t[x].ch[c^1]=f; t[f].fa=x;
update(f); update(x);
}
inline void splay(int x, int tar) {
for(; pa!=tar; rotate(x))
if(t[pa].fa != tar) rotate(wh(x)==wh(pa) ? pa : x);
if(tar==0) root=x;
}
inline void insert(int p) {
int x=root, f=0, v=t[p].v;
while(x) f=x, x= v<t[x].v ? lc : rc;
x=p;
t[f].ch[v>t[f].v]=x; t[x].fa=f;
splay(x, 0);
}
int q[N], p;
void order(int x) {
int l=lc, r=rc;
lc=rc=pa=0; t[x].size=1;
if(l) order(l);
insert(x);
if(r) order(r);
}
void Merge(int x, int y) {
if(x==y) return;
splay(x, 0); splay(y, 0);
if(t[x].size > t[y].size) swap(x, y);
fa[x]=y; root=y;
order(x);
}
int kth(int x, int k) {
splay(x, 0); int lsize=0;
while(x) {
int _=lsize+t[lc].size;
if(k<=_) x=lc;
else if(k==_+1) return x;
else lsize=_+1,x=rc;
}
return -1;
}
}S; int main() {
freopen("in","r",stdin);
n=read(); m=read();
for(int i=1; i<=n; i++) val[i]=read(), fa[i]=i;
S.ini();
for(int i=1; i<=m; i++) x=find(read()), y=find(read()), S.Merge(x, y);
Q=read();
for(int i=1; i<=Q; i++) {
scanf("%s",s); x=find(read()); y=read();
if(s[0]=='B') y=find(y), S.Merge(x, y);
else printf("%d\n", S.kth(x, y));
}
}

BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]的更多相关文章

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

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

  2. BZOJ 2733 [HNOI2012]永无乡(启发式合并+Treap+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2733 [题目大意] 给出n个点,每个点都有自己的重要度,现在有连边操作和查询操作, 查 ...

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

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

  4. bzoj 2733 : [HNOI2012]永无乡 (线段树合并)

    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. Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

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

  8. Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...

  9. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

随机推荐

  1. hdu_1018(斯大林公式/n!的位数)

    题意:求大数n!的位数. 根据n! = (int)log(n!)+1 方法1: log(n!) = log(1*2*3*...*n) = log1+log2+...+logn 方法2: 斯大林公式: ...

  2. UEP-时间

    时间戳转化为Date(or String) SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ...

  3. Django App(一) StartApp

    经过配置Pycharm在上一次的笔记中,已经解决了编写Django web程序调试的问题,这篇将记录Django官网提供的例子程序!          1.查看Pycharm terminal是否可用 ...

  4. 最小生成树之Prim算法

    描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来--小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...

  5. Centos系统下Lamp环境的快速搭建(超详细)

    lamp的搭建对于初学者是一件很头疼的事情,所以借此机会把自己当初快速搭建linux+apche+mysql+php的方法分享大家希望能到你. 工具/原料 虚拟机及Centos操作系统 Linux基本 ...

  6. 怎么使用linux命令重启服务器

    一下的命令都可以重启Linux服务器: 1.shutdown -r now 2.reboot 3.startx

  7. 搭建mybatis时的小问题

    1.源文件中的xml文件经过编译后没有打包到classes中去,在源文件包中写的mapper文件运行时找不到. 解决办法: pom文件build下添加编译时加入xml和resource文件下的所有文件 ...

  8. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  9. hasResultError

    hasResultError 的作用是 让返回的对象可以报错误信息.

  10. Struts的session问题

    问题描述: 在一个action中设置session之后,在jsp中得不到session的值或者在另一个action中得不到session的值. 解决方案: 1.不要把session设置成为静态的,同时 ...