3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 19122  Solved: 8359
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
 
 
 

分析

学了一个神奇的平衡树,叫:finger tree

贴一下模板。。

code

 #include<cstdio>
#include<algorithm>
#define ls ch[cur][0]
#define rs ch[cur][1] using namespace std; const int N = ; int siz[N],val[N],ch[N][],q[N];
int tot,cnt,Root; int getid() {
return tot?q[tot--]:++cnt;
}
void pushup(int cur) {
if (!siz[ls]) return; // -
siz[cur] = siz[ls] + siz[rs];
val[cur] = val[rs];
}
int newNode(int v) {
int cur = getid();
siz[cur] = ;val[cur] = v;
ls = rs = ;
return cur;
}
void copyNode(int x,int y) {
ch[x][] = ch[y][];ch[x][] = ch[y][];
siz[x] = siz[y];val[x] = val[y];
}
int Merge(int x,int y) {
int cur = getid();
val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //---
ls = x;rs = y;
return cur;
}
void lturn(int cur) {
ls = Merge(ls,ch[rs][]);
q[++tot] = rs;
rs = ch[rs][];
}
void rturn(int cur) {
rs = Merge(ch[ls][],rs);
q[++tot] = ls;
ls = ch[ls][];
}
void Maintain(int cur) {
if (rs && siz[ls] > siz[rs] * ) rturn(cur);
if (ls && siz[rs] > siz[ls] * ) lturn(cur);
}
void Insert(int cur,int x) {
if (siz[cur]==) {
ls = newNode(min(val[cur],x));
rs = newNode(max(val[cur],x));
pushup(cur);
return ;
}
if (x > val[ls]) Insert(rs,x);
else Insert(ls,x);
pushup(cur);
Maintain(cur);
}
void Delete(int cur,int fa,int x) {
if (siz[cur]==) {
if (ch[fa][] == cur) copyNode(fa,ch[fa][]); //-----
else copyNode(fa,ch[fa][]);
return;
}
fa = cur;
if (x > val[ls]) Delete(rs,cur,x);
else Delete(ls,cur,x);
pushup(cur);
Maintain(cur);
}
int getrnk(int cur,int x) {
if (siz[cur]==) return ;
//{
// if (x > val[cur]) return 2;
// return 1;
//}
if (x > val[ls])
return getrnk(rs,x) + siz[ls];
else return getrnk(ls,x);
}
int getkth(int cur,int k) {
if (siz[cur]==k) return val[cur];
if (k > siz[ls])
return getkth(rs,k-siz[ls]);
else return getkth(ls,k);
}
int main () {
int T;
scanf("%d",&T);
Root = newNode(1e9);
while (T--) {
int opt,x;
scanf("%d%d",&opt,&x);
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,Root,x);
else if (opt==) printf("%d\n",getrnk(Root,x));
else if (opt==) printf("%d\n",getkth(Root,x));
else if (opt==) printf("%d\n",getkth(Root,getrnk(Root,x)-));
else printf("%d\n",getkth(Root,getrnk(Root,x+))); // ---
}
return ;
}

模板的变迁史:

 #include<cstdio>
#include<algorithm> using namespace std; const int N = ; int siz[N],val[N],ch[N][];
int q[N],tot;
int cnt;
int Root; int getid() {
return tot?q[tot--]:++cnt;
}
void pushup(int x) {
if (!siz[ch[x][]]) return; // -
siz[x] = siz[ch[x][]] + siz[ch[x][]];
val[x] = val[ch[x][]];
}
int newNode(int v) {
int cur = getid();
siz[cur] = ;val[cur] = v;
ch[cur][] = ch[cur][] = ;
return cur;
}
void copyNode(int x,int y) {
ch[x][] = ch[y][];ch[x][] = ch[y][];
siz[x] = siz[y];val[x] = val[y];
}
int merge(int x,int y) {
int cur = getid();
val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //---
ch[cur][] = x;ch[cur][] = y;
return cur;
}
void lturn(int cur) {
ch[cur][] = merge(ch[cur][],ch[ch[cur][]][]);
q[++tot] = ch[cur][];
ch[cur][] = ch[ch[cur][]][];
}
void rturn(int cur) {
ch[cur][] = merge(ch[ch[cur][]][],ch[cur][]);
q[++tot] = ch[cur][];
ch[cur][] = ch[ch[cur][]][];
}
void maintain(int cur) {
if (ch[cur][] && siz[ch[cur][]] > siz[ch[cur][]] * ) rturn(cur);
if (ch[cur][] && siz[ch[cur][]] > siz[ch[cur][]] * ) lturn(cur);
}
void Insert(int cur,int x) {
if (siz[cur]==) {
ch[cur][] = newNode(min(val[cur],x));
ch[cur][] = newNode(max(val[cur],x));
pushup(cur);
return ;
}
if (x > val[ch[cur][]]) Insert(ch[cur][],x);
else Insert(ch[cur][],x);
pushup(cur);
maintain(cur);
}
void Delete(int cur,int fa,int x) {
if (siz[cur]==) {
if (ch[fa][] == cur) copyNode(fa,ch[fa][]); //-----
else copyNode(fa,ch[fa][]);
return;
}
fa = cur;
if (x > val[ch[cur][]]) Delete(ch[cur][],cur,x);
else Delete(ch[cur][],cur,x);
pushup(cur);
maintain(cur);
}
int rnk(int cur,int x) {
if (siz[cur]==) return ;
//{
// if (x > val[cur]) return 2;
// return 1;
//}
if (x > val[ch[cur][]])
return rnk(ch[cur][],x) + siz[ch[cur][]];
else return rnk(ch[cur][],x);
}
int kth(int cur,int k) {
if (siz[cur]==k) return val[cur];
if (k > siz[ch[cur][]])
return kth(ch[cur][],k-siz[ch[cur][]]);
else return kth(ch[cur][],k);
}
int main () {
int T;
scanf("%d",&T);
Root = newNode(1e9);
while (T--) {
int opt,x;
scanf("%d%d",&opt,&x);
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,Root,x);
else if (opt==) printf("%d\n",rnk(Root,x));
else if (opt==) printf("%d\n",kth(Root,x));
else if (opt==) printf("%d\n",kth(Root,rnk(Root,x)-));
else printf("%d\n",kth(Root,rnk(Root,x+))); // ---
}
return ;
}

指针

 // luogu-judger-enable-o2
#include<cstdio>
#include<iostream> using namespace std; const int MAXN = ; struct Node {
int val,size;
Node *ls,*rs;
Node():val(),size(),ls(NULL),rs(NULL) { }
Node(int v,int s,Node *l,Node *r) {
val = v,size = s,ls = l,rs = r;
}
bool isleaf() {
return ls == NULL;
}
void pushup() {
if (!isleaf()) {
size = ls->size + rs->size;
val = max(ls->val,rs->val);
}
}
}pool[MAXN]; Node *newNode(int val,int size,Node *ls,Node *rs) {
static int cnt = ;
pool[cnt] = Node(val,size,ls,rs);
return &pool[cnt++];
} void insert(Node *&cur,int x) {
if (cur==NULL) cur = newNode(x,,NULL,NULL);
else {
if (cur->isleaf()) {
cur->ls = newNode(min(x,cur->val),,NULL,NULL);
cur->rs = newNode(max(x,cur->val),,NULL,NULL);
}
else {
if (x > cur->ls->val) insert(cur->rs,x);
else insert(cur->ls,x);
}
cur -> pushup();
}
}
void erase(Node *cur,Node *fa,int x) {
if (cur->isleaf()) {
if (fa->ls == cur) *fa = *fa->rs;
else *fa = *fa->ls;
}
else {
if (x > cur->ls->val) erase(cur->rs,cur,x);
else erase(cur->ls,cur,x);
cur -> pushup();
}
}
int rnk(Node *cur,int x) {
if (cur->isleaf()) {
if (x > cur->val) return ;
return ;
}
else {
if (x > cur->ls->val)
return rnk(cur->rs,x)+cur->ls->size;
else return rnk(cur->ls,x);
}
}
int kth(Node *cur,int k) {
if (cur->isleaf()) return cur->val;
else {
if (k > cur->ls->size)
return kth(cur->rs,k - cur->ls->size);
else return kth(cur->ls,k);
}
}
int main () {
int T;
scanf("%d",&T);
Node *root = NULL;
while (T--) {
int opt,x;
scanf("%d%d",&opt,&x);
if (opt==) insert(root,x);
else if (opt==) erase(root,root,x);
else if (opt==) printf("%d\n",rnk(root,x));
else if (opt==) printf("%d\n",kth(root,x));
else if (opt==) printf("%d\n",kth(root,rnk(root,x)-));
else printf("%d\n",kth(root,rnk(root,x+)));
}
return ;
}

3224: Tyvj 1728 普通平衡树(finger tree)的更多相关文章

  1. 【bzoj】3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 10097  Solved: 4302[Submit][St ...

  2. BZOJ 3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9629  Solved: 4091[Submit][Sta ...

  3. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  4. BZOJ 3224: Tyvj 1728 普通平衡树 treap

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  5. BZOJ 3224: Tyvj 1728 普通平衡树 vector

    3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...

  6. BZOJ 3224: Tyvj 1728 普通平衡树(BST)

    treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...

  7. BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 22483  Solved: 10130[Submit][S ...

  8. 3224: Tyvj 1728 普通平衡树(新板子)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17048  Solved: 7429[Submit][St ...

  9. 【BZOJ】3224: Tyvj 1728 普通平衡树(某不科学的oj)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3224 无力吐槽,无力吐槽,无力吐槽....... bzoj竟然不能用time(0)我竟然不造!!re ...

随机推荐

  1. easyUI 实现异步tree

    html: <ul id="relInfoTree" class="easyui-tree"></ul> js: $(document) ...

  2. Android RxJava2+Retrofit2单文件下载监听进度封装

    RxJava2和Retrofit2用的越来越多,最近也在封装一个通用的网络请求库,其中就包括了单文件下载的方法,所以这里进行记录.文末附带Demo 由于网上很多的方法都是使用拦截器进行进度的监听,个人 ...

  3. Python之自定义封装一个简单的Log类

    参考:http://www.jb51.net/article/42626.htm 参考:http://blog.csdn.net/u011541946/article/details/70198676 ...

  4. SQL 语句实现行转列

    CREATE TABLE #tempcloum( [productNum] varchar() null, [year1] decimal not null, [year2] decimal not ...

  5. 实战:ADFS3.0单点登录系列-集成MVC

    本文将讲解如何让MVC应用程序与ADFS集成,完成认证的过程. 目录: 实战:ADFS3.0单点登录系列-总览 实战:ADFS3.0单点登录系列-前置准备 实战:ADFS3.0单点登录系列-ADFS3 ...

  6. LeetCode Valid Palindrome 有效回文(字符串)

    class Solution { public: bool isPalindrome(string s) { if(s=="") return true; ) return tru ...

  7. pta 编程题10 Root of AVL Tree

    其它pta数据结构编程题请参见:pta 这道题考察平衡二叉查找树的插入. 为了保证二叉查找树的平衡,当一个结点的左右子树的高度差大于1时就要进行调整. 分为以下四种情况: 插入新节点后,以及旋转之后, ...

  8. ZooKeeper保证之单一视图(Single System Image)

    由于ZooKeeper的数据模型简单且全部在内存中,ZooKeeper的速度非常快.它提供了一系列保证(Guarantees): • 顺序一致性(Sequential Consistency) • 原 ...

  9. IOS Modal(切换另外控件器方式)

    ● 除了push之外,还有另外一种控制器的切换方式,那就是Modal ● 任何控制器都能通过Modal的形式展示出来 ● Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止 ...

  10. Linux基础精华(转)

    Linux基础精华 (继续跟新中...) 常用命令: Linux shell 环境 让你提升命令行效 率的 Bash 快捷键 [完整版] 设置你自己的liux alias Linux的Find使用 L ...