(treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
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
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
84185
492737
HINT
Source
STL用法练手题。。。(手动滑稽)
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
vector<int>A;
int main(){
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
if(opt==)A.insert(upper_bound(A.begin(),A.end(),x),x);
else if(opt==)A.erase(lower_bound(A.begin(),A.end(),x));
else if(opt==)printf("%d\n",lower_bound(A.begin(),A.end(),x)-A.begin()+);
else if(opt==)printf("%d\n",A[x-]);
else if(opt==)printf("%d\n",*(lower_bound(A.begin(),A.end(),x)-));
else printf("%d\n",*upper_bound(A.begin(),A.end(),x));
}
return ;
}
(学习treap中,到时候再发)
更新:
液我A了!!!
先上代码
// It is made by XZZ
#include<cstdio>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define Ls tree[now].ls
#define Rs tree[now].rs
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
struct node{
int ls,rs,value,rand,sum,size;
node(){ls=rs=value=rand=sum=size=;}
}tree[];
int root=,siz=;
ll seed=;
il int Rand(){return seed=seed*48271LL%;}
il vd reset(int now){
tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
}
il vd lrot(int&now){
int ls=tree[now].ls;
tree[now].ls=tree[ls].rs,tree[ls].rs=now;
tree[ls].size=tree[now].size;reset(now);now=ls;
}
il vd rrot(int&now){
int rs=tree[now].rs;
tree[now].rs=tree[rs].ls,tree[rs].ls=now;
tree[rs].size=tree[now].size;reset(now);now=rs;
}
il vd ins(int&now,int num){
if(now==){
++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
return;
}
++tree[now].size;
if(tree[now].value==num)++tree[now].sum;
else if(num<tree[now].value){
ins(Ls,num);
if(tree[Ls].rand<tree[now].rand)lrot(now);
}else{
ins(Rs,num);
if(tree[Rs].rand<tree[now].rand)rrot(now);
}
}
il vd del(int&now,int num){
if(now==)return;
if(tree[now].value==num){
if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
if(!Ls||!Rs)now=Ls|Rs;
else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
else rrot(now),del(now,num);
return;
}
--tree[now].size;
if(num<tree[now].value)del(Ls,num);
else del(Rs,num);
}
il int getrank(int now,int num){
if(now==)return ;
if(tree[now].value==num)return tree[Ls].size+;
if(num>tree[now].value)return tree[Ls].size+tree[now].sum+getrank(Rs,num);
else return getrank(Ls,num);
}
il int getnum(int now,int num){
if(num<=tree[Ls].size)return getnum(Ls,num);
else if(num>tree[Ls].size+tree[now].sum)return getnum(Rs,num-tree[Ls].size-tree[now].sum);
else return tree[now].value;
}
int ans;
il vd lower(int now,int num){
if(now==)return;
if(tree[now].value<num)ans=now,lower(Rs,num);
else lower(Ls,num);
}
il vd upper(int now,int num){
if(now==)return;
if(tree[now].value>num)ans=now,upper(Ls,num);
else upper(Rs,num);
}
int main(){
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
switch(opt){
case :ins(root,x);break;
case :del(root,x);break;
case :printf("%d\n",getrank(root,x));break;
case :printf("%d\n",getnum(root,x));break;
case :ans=,lower(root,x),printf("%d\n",tree[ans].value);break;
case :ans=,upper(root,x),printf("%d\n",tree[ans].value);break;
}
}
return ;
}
// It is made by XZZ
#include<cstdio>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define Ls tree[now].ls
#define Rs tree[now].rs
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
struct node{
int ls,rs,value,rand,sum,size;
node(){ls=rs=value=rand=sum=size=;}
}tree[];
int root=,siz=;
ll seed=;
il int Rand(){return seed=seed*48271LL%;}
il vd reset(int now){
tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
}
il vd lrot(int&now){
int ls=tree[now].ls;
tree[now].ls=tree[ls].rs,tree[ls].rs=now;
tree[ls].size=tree[now].size;reset(now);now=ls;
}
il vd rrot(int&now){
int rs=tree[now].rs;
tree[now].rs=tree[rs].ls,tree[rs].ls=now;
tree[rs].size=tree[now].size;reset(now);now=rs;
}
il vd ins(int&now,int num){
if(now==){
++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
return;
}
++tree[now].size;
if(tree[now].value==num)++tree[now].sum;
else if(num<tree[now].value){
ins(Ls,num);
if(tree[Ls].rand<tree[now].rand)lrot(now);
}else{
ins(Rs,num);
if(tree[Rs].rand<tree[now].rand)rrot(now);
}
}
il vd del(int&now,int num){
if(now==)return;
if(tree[now].value==num){
if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
if(!Ls||!Rs)now=Ls|Rs;
else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
else rrot(now),del(now,num);
return;
}
--tree[now].size;
if(num<tree[now].value)del(Ls,num);
else del(Rs,num);
}
il int getrank(int now,int num){
int Rank=;
while(now)if(tree[now].value==num)return tree[Ls].size++Rank;
else if(num>tree[now].value)Rank+=tree[Ls].size+tree[now].sum,now=Rs;
else now=Ls;
}
il int getnum(int now,int num){
while()
if(num<=tree[Ls].size)now=Ls;
else if(num>tree[Ls].size+tree[now].sum)num-=tree[Ls].size+tree[now].sum,now=Rs;
else return tree[now].value;
}
il int lower(int now,int num){
int ret;
while(now)if(tree[now].value<num)ret=tree[now].value,now=Rs;
else now=Ls;
return ret;
}
il int upper(int now,int num){
int ret;
while(now)if(tree[now].value>num)ret=tree[now].value,now=Ls;
else now=Rs;
return ret;
}
int main(){
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
switch(opt){
case :ins(root,x);break;
case :del(root,x);break;
case :printf("%d\n",getrank(root,x));break;
case :printf("%d\n",getnum(root,x));break;
case :printf("%d\n",lower(root,x));break;
case :printf("%d\n",upper(root,x));break;
}
}
return ;
}
这样在cogs上可以从1.90s下降到1.70s
在洛谷上可以从164ms上升到259ms(大雾)
在bzoj上可以从300ms下降到296ms
所以非递归到底有没有用???
(treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树的更多相关文章
- 【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树
[替罪羊树]bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树 bzoj 洛谷 cogs 先长点芝士 替罪羊树也是一种很好写的平衡树qwq..替罪 ...
- BZOJ3224 洛谷3369 Tyvj 1728 普通平衡树 splay
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3224 题意概括 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. ...
- BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 22483 Solved: 10130[Submit][S ...
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 7390 Solved: 3122 [Submit][S ...
- bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5354 Solved: 2196[Submit][Sta ...
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- bzoj3224: Tyvj 1728 普通平衡树(平衡树)
bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...
- BZOJ 3224: Tyvj 1728 普通平衡树 treap
3224: Tyvj 1728 普通平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除 ...
随机推荐
- Java并发基础概念
Java并发基础概念 线程和进程 线程和进程都能实现并发,在java编程领域,线程是实现并发的主要方式 每个进程都有独立的运行环境,内存空间.进程的通信需要通过,pipline或者socket 线程共 ...
- [转]MVVM架构~mvc,mvp,mvvm大话开篇
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.作为一种新的模式,MVP与MVC有着一 ...
- 判断是否POST提交
if(strtolower($_SERVER['REQUEST_METHOD']) == 'post'){} //判断是否POST提交
- pymongo的安装和使用
1.安装 MongoDB的python接口pymongo的安装方法有多种,如源码.easy_install.pip都可以.采用pip安装,很简单. pip install pymongo 安装完成后可 ...
- HDFS的Write过程
hadoop中重要的组成部分HDFS,它所发挥的重要作用是进行文件的后端存储.HDFS针对的是低端的服务器,场景为读操作多.写操作少的情况.在分布式存储情况下,比较容易出现的情况是数据的损害,为了保证 ...
- 二叉查找树(二叉排序树)(C语言)
#include<stdio.h> #include "fatal.h" struct TreeNode; typedef struct TreeNode *Posit ...
- 安装Win7时删除系统保留的100M隐藏分区
原创文章,作者:lenbs,如若转载,请注明出处:https://www.smbinn.com/delwindows7100m.html 安装windows7新建磁盘分区时系统会自动创建100M的保留 ...
- C++练习 | 创建并倒序输出不带头结点的链表
#include <iostream> #include <cstdio> #include <stdlib.h> #include <stack> u ...
- 完全卸载MySQL数据库,实现重装
一.在控制面板,卸载MySQL的所有组件 控制面板——>所有控制面板项——>程序和功能,卸载所有和MySQL有关的程序 二.找到你的MysQL安装路径,看还有没有和MySQL有关的文件夹, ...
- 微信小程序 - bindtap等事件传参
什么是事件事件是视图层到逻辑层的通讯方式. 事件可以将用户的行为反馈到逻辑层进行处理. 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数. 事件对象可以携带额外信息,如 id, ...