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. 一位学长的学习建议(java方向)

    1.前台总得有个拿的出手的页面能力吧,ajax,jquery不说精通但是至少能看懂,能根据业务需求来改吧. 2.数据库方面至少得玩过mysql,DB2,Oracle中的两个以上吧.hibernate或 ...

  2. 解决windows7系统的快捷方式无法添加到任务栏

    #以下4条,进入cmd命令界面下逐个执行cmd /k reg add "HKEY_CLASSES_ROOT\lnkfile" /v IsShortcut /fcmd /k reg ...

  3. 【MFC】可以换行的编辑框

    在mfc中编辑框允许输入多行时,换行符被表示为<归位><换行>即“\r\n”,用ascii码表示为13 10 如果为编辑框中想要输入换行,就请将编辑框的属性: Auto HSc ...

  4. pysnmp程序

    功能 访问远程交换机snmp数据,写入本地influxdb数据库 #!/usr/bin/env python # -*- encoding: utf-8 -*- import os, yaml, ti ...

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

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

  6. ubuntu14.04安装gradle

    一.下载gradle $ wget https:////services.gradle.org/distributions/gradle-3.5.1-all.zip $ sudo unzip grad ...

  7. IOS view拖拽(触摸事件)

    • iOS中的事件可以分为3大类型 触摸事件 加速计事件 远程控制事件 响应者对象 • 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事 件.我们称之为“响应 ...

  8. 2017.12.1 如何用java写出一个菱形图案

    上机课自己写的代码 两个图形原理都是一样的 1.一共有仨个循环 注意搞清楚每一层循环需要做的事情 2.第一层循环:是用来控制行数 3.第二层循环控制打印空格数 4.第三层循环是用来循环输出星星 imp ...

  9. GPU && CUDA:主机和设备间数据传输测试

    数据传输测试,先从主机传输到设备,再在设备内传输,再从设备传输到主机. H-->D D-->D D-->H // moveArrays.cu // // demonstrates C ...

  10. 【6.20校内test】

    反正考的不是很好吧,赶脚炸了啊qwq 然后这两天一直在忙一些神奇的事情,所以没有整理完 手动@water_lift T1:大美江湖: [题目背景] 细雪飘落长街,枫叶红透又一年 不只为故友流连,其实我 ...