treap启发式合并
注意输入v要在建根的前面。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
using namespace std;
const int maxn = + ;
int tot = , f[maxn], n, Q, v[maxn];
char cmd;
struct Node{
int r, v, s;
Node* ch[];
void maintain(){
s = ch[] -> s + ch[] -> s + ;
return ;
}
}*null = new Node(), *root[maxn], nodes[maxn];
queue<Node*> RAM;
Node* node(){
Node* o;
if(!RAM.empty()) o = RAM.front(), RAM.pop();
else o = &nodes[tot ++];
return o;
}
void del(Node* &o){
RAM.push(o);
o = null;
return ;
}
void init(Node* &o, int v){
o -> ch[] = o -> ch[] = null;
o -> s = ;
o -> r = rand();
o -> v = v;
return ;
}
void rotate(Node* &o, int d){
Node* k = o -> ch[d ^ ]; o -> ch[d ^ ] = k -> ch[d]; k -> ch[d] = o;
o -> maintain(); k -> maintain(); o = k; return ;
}
void insert(Node* &o, int v){
if(o == null) o = node(), init(o, v);
else{
int d = v > o -> v;
insert(o -> ch[d], v);
if(o -> ch[d] -> r > o -> r) rotate(o, d ^ );
else o -> maintain();
}
return ;
}
void remove(Node* &o, int v){
if(v == o -> v){
if(o -> ch[] != null && o -> ch[] != null){
int d = o -> ch[] -> r > o -> ch[] -> r;
rotate(o, d); remove(o -> ch[d], v);
}
else{
Node* k = o;
if(o -> ch[] != null) o = o -> ch[];
else o = o -> ch[];
del(k);
}
}
else remove(o -> ch[v > o -> v], v);
if(o != null) o -> maintain();
return ;
}
void print(Node* &o){
if(o == null) return ;
print(o -> ch[]);
printf("%d ", o -> v);
print(o -> ch[]);
return ;
}
int kth(Node* &o, int k){
if(o -> s < k || k < ) return -;
if(o -> ch[] -> s + == k) return o -> v;
if(o -> ch[] -> s >= k) return kth(o -> ch[], k);
return kth(o -> ch[], k - o -> ch[] -> s - );
}
void merge(Node* &left, Node* &right){
if(left == null) return ;
merge(left -> ch[], right);
merge(left -> ch[], right);
insert(right, left -> v);
del(left); return ;
}
int findset(int x){
return x == f[x] ? x : f[x] = findset(f[x]);
}
void merge(int a, int b){
a = findset(a); b = findset(b);
if(a == b) return ;
if(root[a] -> s > root[b] -> s) swap(a, b);
merge(root[a], root[b]);
f[a] = b; return ;
}
void read(int &x){
x = ; int sig = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') sig = -; ch = getchar(); }
while(isdigit(ch)) x = * x + ch - '', ch = getchar();
x *= sig; return ;
}
void init(){
srand(time());
null -> s = ;
read(n); read(Q);
for(int i = ; i <= n; i ++) read(v[i]);
for(int i = ; i <= n; i ++) f[i] = i, root[i] = node(), init(root[i], v[i]);
return ;
}
void work(){ return ;
}
void print(){ return ;
}
int main(){
init();
work();
print();
return ;
}
treap启发式合并的更多相关文章
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- 【bzoj2733】[HNOI2012]永无乡 Treap启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- BZOJ4919 大根堆(动态规划+treap+启发式合并)
一个显然的dp是设f[i][j]为i子树内权值<=j时的答案,则f[i][j]=Σf[son][j],f[i][a[i]]++,f[i][a[i]+1~n]对其取max.这样是可以线段树合并的, ...
- 【20181026T2】**图【最小瓶颈路+非旋Treap+启发式合并】
题面 [错解] 最大最小?最小生成树嘛 蛤?还要求和? 点分治? 不可做啊 写了个MST+暴力LCA,30pts,140多行 事后发现30分是给dijkstra的 woc [正解] 树上计数问题:①并 ...
- 【bzoj2733】永无乡(无旋treap启发式合并 + 并查集)
传送门 题目分析 起初每个岛都是一个平衡树, 并查集的祖先都是自己.合并两岛时,pri较小的祖先会被作为合并后的祖先, 而两颗平衡树采用启发式合并.查询k值就是基本操作. code #include& ...
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- 启发式合并&线段树合并/分裂&treap合并&splay合并
启发式合并 有\(n\)个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素. 我们可以用平衡树/set维护集合. 对于合并两个\(A,B\),如果\(|A|<|B|\),那么 ...
- BZOJ 2733 [HNOI2012]永无乡(启发式合并+Treap+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2733 [题目大意] 给出n个点,每个点都有自己的重要度,现在有连边操作和查询操作, 查 ...
- SCUT - 106 - 花式ac - 主席树/启发式合并Treap
https://scut.online/p/106 错在这组样例,发现是离散化之后,对k访问的时候也是应该访问离散化之后的k. 12 4 1 1 2 2 5 5 4 4 3 3 2 1 1 3 3 5 ...
随机推荐
- 数据库框架 Litepal
1.导包 dependencies { compile 'org.litepal.android:core:1.4.1' } 2.在asstes中建立litepal.xml文件 <?xml ...
- ALS数学点滴
其中,$n_{u_i}$表示用户$i$评分的电影数目,$n_{m_j}$表示对电影$j$评分的用户数目.设$I_i$表示用户$i$所评分的电影集合,则$n_{u_i}$是$I_i$的基数,同样的,$I ...
- Meth | 安装Linux Mint 18以后grub2 win10启动引导项丢失??!!
进入mint,打开终端输入:sudo update-grub2
- 化繁为简,无需后端。巧用Yql+rss,搭建我的个人网站
[本文含有大量的心理描写,没耐心的看官直接跳转到末尾即可] 前言: 最近做好了个人网站.很多人都喜欢用WordPress弄一个自己的博客之类的,但其实我觉得没这个必要,Lofter的功能.界面神马的于 ...
- 优雅退出 Android 应用程序的 6 种方式
我们先来看看几种常见的退出方法(不优雅的方式) 一.容器式 建立一个全局容器,把所有的Activity存储起来,退出时循环遍历finish所有Activity import java.util.Arr ...
- C#实现发送邮件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 条件注释判断浏览器版本<!--[if lt IE 9]>(转载)
<!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![ ...
- 强引用,弱引用,4种Java引用浅解(涉及jvm垃圾回收)
http://www.jb51.net/article/49085.htm http://www.jb51.net/article/49085.htm
- tomcat报404
很久没有用eclipse了,尝试了使用下,竟然将简单的配置tomcat都忘了. 自己新建一个工程,在tomcat发布以后,报404,经查Serves下的web.xml中,欢迎页面是index.jsp, ...
- linux dd命令测试U盘读写速度
1. dd命令简述: if=输入文件, of=输出文件, ibs=一次读取字节数, obs=一次写入字节数, bs=设置一次读取写入的字节数, skip=跳过的bs数, count=拷贝的块数 2. ...