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. css钻石旋转实现

    css钻石旋转实现: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  2. Java框架:spring框架整合hibernate框架的xml配置(使用注解的方式)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. Weblogic 10.3.6.0 集群搭建

    Weblogic 集群搭建 Oracle的Weblogic分开发者版本和生产版本,有32位和64位.一般生产版本的weblogic是64位的,安装文件是一个大小为1G多的jar包.去oracle官网上 ...

  4. hive 报错FAILED: Error in metadata: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient FAILED: Execu

    使用hive一段时间以后,今天在使用的时候突然报错,如下: hive> show databases;FAILED: Error in metadata: java.lang.RuntimeEx ...

  5. linux 命令——17 whereis(转)

    whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 和 find相比,whereis查找的速度 ...

  6. IE的Trident引擎下实现C++和Javascript相互调用

    我们知道实现C++和Javascript通讯有下表5种接口: 引擎 编写语言 API接口 C.C++与JavaScript交互(变量.函数.类) vc2005编译静态库的大小 示例EXE的大小 执行. ...

  7. docker 快速搭建 mysql

    准备工作 系统 centos7 切换阿里源 #备份资源文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo ...

  8. iptables (2) 基本配置

    iptables 基本命令使用举例 一.链的基本操作 1.清除所有的规则.1)清除预设表filter中所有规则链中的规则.# iptables -F -F, --flush [chain] Flush ...

  9. Android(java)学习笔记93:为什么局部内部类只能访问外部类中的 final型的常量

    为什么匿名内部类参数必须为final类型: 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变 ...

  10. iOS 集成支付宝过程中 我遇到的一些坑,请大家注意啦(ALI69错误,ALI64错误)

    支付宝很早一段时间就集成了,之前由于一直忙于开发就没有总结,今天整理桌面的时候看到,当时做支付时候的一些散落的笔记,就稍微整理一下,给大家分享一下. 第一:当时调用支付宝的时候,总是调不起来,进过断点 ...