Treap 的合并

首先感谢 @Capella 的DeBug

其次,这是由一个 & 号引发的血案

注意对于所有修改操作都要 &

Treap的合并, 启发式合并,对于每一个节点都 insert ,注意垃圾回收

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int MAXN = 500005;
int init() {
int rv = 0, fh = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') fh = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
rv = (rv<<1) + (rv<<3) + c - '0';
c = getchar();
}
return fh * rv;
}
int pool[MAXN], top, n, m, id[MAXN], q;
struct UFS {
int fa[MAXN];
void unit() {
for(int i = 1; i <= n; i++) fa[i] = i;
}
int find(int x) {
if(x != fa[x]) return fa[x] = find(fa[x]);
return fa[x];
}
}ufs;
struct node{
int val, dat, num, size, l, r;
}a[MAXN];
struct Treap{
int New(int x, int num) {
int ret = pool[++top];
a[ret].val = x;
a[ret].num = num;
a[ret].dat = rand();
a[ret].size = 1;
a[ret].l = a[ret].r = 0;
return ret;
}
void del(int &rt) {pool[top--] = rt;rt = 0;}
void PushUp(int rt) {
a[rt].size = a[a[rt].l].size + a[a[rt].r].size + 1;
}
void zig(int &rt) {
int nxt = a[rt].l;
a[rt].l = a[nxt].r; a[nxt].r = rt; rt = nxt;
PushUp(a[rt].r);
PushUp(rt);
}
void zag(int &rt) {
int nxt = a[rt].r;
a[rt].r = a[nxt].l; a[nxt].l = rt; rt = nxt;
PushUp(a[rt].l);
PushUp(rt);
}
void Insert(int &rt, int x, int num) {
if(!rt) {
rt = New(x, num);
return;
}
if(x < a[rt].val) {
Insert(a[rt].l, x, num);
if(a[a[rt].l].dat > a[rt].dat) zig(rt);
}else {
Insert(a[rt].r, x, num);
if(a[a[rt].r].dat > a[rt].dat) zag(rt);
}
PushUp(rt);
}
int GetNum(int rt, int x) {
if(!rt) return -1;
if(a[a[rt].l].size >= x) return GetNum(a[rt].l, x);
if(a[a[rt].l].size + 1 >=x) return a[rt].num;
return GetNum(a[rt].r,x - 1 - a[a[rt].l].size);
}
void merge(int /*x*/&x, int &y) {
if(!y) return;
if(a[y].l)
merge(x, a[y].l);
if(a[y].r)
merge(x, a[y].r);
Insert(x, a[y].val, a[y].num);del(y);
}
}bst;
void merge(int u, int v) {
int r1 = ufs.find(u), r2 = ufs.find(v);
if(r1 != r2) {
if(a[id[r1]].size < a[id[r2]].size) {
ufs.fa[r1] = r2;
bst.merge(id[r2], id[r1]);
}else {
ufs.fa[r2] = r1;
bst.merge(id[r1], id[r2]);
}
}
}
int main() {
n = init(); m = init();
ufs.unit();
for(int i = 0; i < MAXN; i++) pool[i] = i;
for(int i = 1; i <= n; i++) {
int t = init();
id[i] = bst.New(t, i);
}
for(int i = 1; i <= m; i++) {
int u = init(), v = init();
if(!u || !v) continue;
merge(u, v);
}
q = init();
for(int i = 1; i <= q; i++) {
char t;
scanf(" %c ", &t);
if(t == 'Q') {
int x = init(), k = init();
printf("%d\n", bst.GetNum(id[ufs.find(x)], k));
}else {
int u = init(), v = init();
if(!u || !v) continue;
merge(u, v);
}
}
return 0;
}

洛谷 [P3224] 永无乡的更多相关文章

  1. 洛谷P3224 永无乡 [HNOI2012] 线段树/splay/treap

    正解:线段树合并 解题报告: 传送门! 这题也是有很多解法,eg:splay,treap,... 然而我都不会我会学的QAQ! 反正今天就只讲下线段树合并怎么做QAQ 首先看到这样子的说第k重要的是什 ...

  2. 【Luogu】P3224永无乡(splay)

    题目链接 splay模板,启发式合并(其实就是暴力插入)即可. 顺便吐槽时限,带垃圾回收而已……不至于最后一个点死活不让过吧? #include<cstdio> #include<c ...

  3. 洛谷 P3224 [HNOI2012]永无乡 解题报告

    P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...

  4. 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)

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

  5. 洛谷 P3224 [HNOI2012]永无乡

    题面 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛 ...

  6. 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡

    题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...

  7. 【题解】永无乡 [HNOI2012] [BZOJ2733] [P3224]

    [题解]永无乡 [HNOI2012] [BZOJ2733] [P3224] [题目描述] 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要 ...

  8. P3224 [HNOI2012]永无乡 题解

    P3224 [HNOI2012]永无乡 题解 题意概括 有若干集合,每个集合最初包含一个值,和一个编号1~n.两个操作:合并两个集合,查询包含值x的集合中第k大值最初的集合编号. 思路 维护集合之间关 ...

  9. bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)

    [HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...

随机推荐

  1. Web项目之Django基础

    Django目录: python项目Django(web服务) python项目Django(HTTP协议) python项目Django(Django的安装与使用) python项目Django(U ...

  2. for循环输出i为同一值的问题

    使用闭包将变量i的值保护起来. //sava1:加一层闭包,i以函数参数形式传递给内层函数 for( var i=0; i<ps.length; i++ ) { (function(arg){ ...

  3. VC-基础:MFC单文档程序架构解析

    MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一一个在程序形成的时候就存在 ...

  4. Caused by: java.lang.ClassNotFoundException: java.com.bj186.ssm.controller.UserController

    在搭建SpringMVC的时候,遇到的这个问题真的很奇葩, 找不到UserController这个类 这明明不就在工程目录下吗? 经过了一番艰苦卓绝的斗争, 才发现原来是包导少了 之前导入的包是: & ...

  5. Python基础篇 -- 列表

    3.2 列表的增删改查 ​ 列表使用 [] 来表示,列表中每个元素与元素之间用逗号隔开 ​ 列表也有索引和切片 # 切片切出来的也是列表 lst = ["梅西", "内马 ...

  6. hibernate的注解

    1.many-to-one @ManyToOne @JoinColumn(name = "user_id") 2.many-to-many /** * 双向关联关系中,有且仅有一端 ...

  7. PHP 头部utf-8

    只是自己用的一些存储,请各位看官大大勿怪. header("Content-Type: text/html;charset=utf-8"); 2019年04月10日

  8. HDU-1009-肥鼠交易

    这题是一道简单的可拆分的贪心题目,需要注意的是,我们定义的结构体里面都应该用double类型, 或者float类型,不然两个int相除,就失去了精度(强转也可以). #include <cstd ...

  9. 【分块】[HNOI2010]弹飞绵羊&分块大法祭

    分块(似乎还有一种动态树(LCT)做法) 第一次学习分块,似乎有点小激动 这是黄学长的分块入门博客「分块」数列分块入门1 – 9 by hzwer 题目描述 某天,Lostmonkey发明了一种超级弹 ...

  10. ELK踩过的各种坑 6.4版本

    一.elasticsearch 1.服务正常启动,但不能正常访问 [root@linux-node1 elasticsearch]# systemctl start elasticsearch [ro ...