【bzoj3196】 Tyvj1730—二逼平衡树
http://www.lydsy.com/JudgeOnline/problem.php?id=3196 (题目链接)
题意
1.查询k在区间内的排名;2.查询区间内排名为k的值;3.修改某一位值上的数值;4.查询k在区间内的前驱(前驱定义为小于x,且最大的数);5.查询k在区间内的后继(后继定义为大于x,且最小的数)
Solution
修改不好搞,主席树套树状数组空间炸,最好的选择→_→:线段树套treap。
对于操作2,我们二分找到一个排名大于$k$的最小的数,然后查询这个数的前驱即可。
细节
查询前驱和后继的时候要特判一下没有找到的情况。
代码
// bzoj3196
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std; const int maxn=50010;
int a[maxn],n,m;
struct node {
int son[2],l,r,w,val,rnd,size,tree;
int& operator [] (int x) {return son[x];}
}; namespace Treap {
int sz;node tr[maxn*50];
void pushup(int x) {
tr[x].size=tr[tr[x][0]].size+tr[tr[x][1]].size+tr[x].w;
}
void rotate(int &x,int p) {
int y=tr[x][p];
tr[x][p]=tr[y][p^1];tr[y][p^1]=x;x=y;
pushup(tr[y][p^1]);pushup(y);
}
void insert(int &k,int x) {
if (!k) {tr[k=++sz].val=x;tr[k].rnd=rand();tr[k].size=tr[k].w=1;return;}
int p=x>tr[k].val;tr[k].size++;
if (x==tr[k].val) {tr[k].w++;return;}
insert(tr[k][p],x);
if (tr[tr[k][p]].rnd>tr[k].rnd) rotate(k,p);
}
void erase(int &k,int x) {
if (!k) return;
if (tr[k].val==x) {
if (tr[k].w>1) {tr[k].w--;tr[k].size--;return;}
if (tr[k][0]*tr[k][1]==0) k=tr[k][0]+tr[k][1];
else rotate(k,tr[tr[k][1]].rnd>tr[tr[k][0]].rnd),erase(k,x);
}
else tr[k].size--,erase(tr[k][x>tr[k].val],x);
}
int rank(int k,int x) {
if (!k) return 0;
if (x<=tr[k].val) return rank(tr[k][0],x);
else return rank(tr[k][1],x)+tr[tr[k][0]].size+tr[k].w;
}
int find(int k,int x) {
if (!k) return -1;
if (tr[tr[k][0]].size<x && x<=tr[tr[k][0]].size+tr[k].w) return tr[k].val;
else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);
else return find(tr[k][1],x-tr[tr[k][0]].size-tr[k].w);
}
int pref(int k,int x) {return find(k,rank(k,x));}
int suff(int k,int x) {return find(k,rank(k,x+1)+1);}
} namespace Segtree {
node tr[maxn<<2];
void build(int k,int s,int t) {
tr[k].l=s;tr[k].r=t;
for (int i=s;i<=t;i++) Treap::insert(tr[k].tree,a[i]);
if (s==t) return;
int mid=(s+t)>>1;
build(k<<1,s,mid);build(k<<1|1,mid+1,t);
}
void modify(int k,int p,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
Treap::erase(tr[k].tree,a[p]);
Treap::insert(tr[k].tree,val);
if (l==r) return;
if (p<=mid) modify(k<<1,p,val);
else modify(k<<1|1,p,val);
}
int rank(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) return Treap::rank(tr[k].tree,val);
if (t<=mid) return rank(k<<1,s,t,val);
else if (s>mid) return rank(k<<1|1,s,t,val);
else return rank(k<<1,s,mid,val)+rank(k<<1|1,mid+1,t,val);
}
int pref(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) {
int tmp=Treap::pref(tr[k].tree,val);
return tmp==-1 ? -inf : tmp;
}
if (t<=mid) return pref(k<<1,s,t,val);
else if (s>mid) return pref(k<<1|1,s,t,val);
else return max(pref(k<<1,s,mid,val),pref(k<<1|1,mid+1,t,val));
}
int suff(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) {
int tmp=Treap::suff(tr[k].tree,val);
return tmp==-1 ? inf : tmp;
}
if (t<=mid) return suff(k<<1,s,t,val);
else if (s>mid) return suff(k<<1|1,s,t,val);
else return min(suff(k<<1,s,mid,val),suff(k<<1|1,mid+1,t,val));
}
int find(int s,int t,int k) {
int l=0,r=1e8,res;
while (l<=r) {
int mid=(l+r)>>1;
if (rank(1,s,t,mid)>=k) r=mid-1,res=mid;
else l=mid+1;
}
return pref(1,s,t,res);
}
}
using namespace Segtree; int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
for (int op,x,y,k,i=1;i<=m;i++) {
scanf("%d%d%d",&op,&x,&y);
if (op==1) scanf("%d",&k),printf("%d\n",rank(1,x,y,k)+1);
if (op==2) scanf("%d",&k),printf("%d\n",find(x,y,k));
if (op==4) scanf("%d",&k),printf("%d\n",pref(1,x,y,k));
if (op==5) scanf("%d",&k),printf("%d\n",suff(1,x,y,k));
if (op==3) modify(1,x,y),a[x]=y;
}
return 0;
}
【bzoj3196】 Tyvj1730—二逼平衡树的更多相关文章
- BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】
BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...
- [BZOJ3196][Tyvj1730]二逼平衡树
[BZOJ3196][Tyvj1730]二逼平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询 \(k\) 在区间内的排名 查询区间内排名为 \ ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- bzoj3196 [TYVJ1730]二逼平衡树 树套树 线段树套替罪羊树
人傻自带大常数 二分的可行性证明: 贴近他的正确答案不会被当作次优解删掉,因为,若二分在他右边发生,那么二分一定会把左边作为优解,左边同理,所以他一定是被扣掉的所以最后一个小于等于一定是正确答案 #i ...
- bzoj3196:Tyvj1730二逼平衡树
传送门 暴力啊,直接树套树上啊 线段树套splay,卡卡常就直接A了 代码: #include<cstdio> #include<iostream> #include<a ...
- [BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)
传送门 至少BZOJ过了,其他的直接弃. 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的 ...
- 【BZOJ3196】二逼平衡树(树状数组,线段树)
[BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...
- [TYVJ1730]二逼平衡树
[TYVJ1730]二逼平衡树 题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查 ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
随机推荐
- CSS之Header--我的头部我做主
<div class='header'> <div class="header-left"> <span class='iconfont back-i ...
- 20155206《网络对抗》Web安全基础实践
20155206<网络对抗>Web安全基础实践 实验后问题回答 (1)SQL注入攻击原理,如何防御 攻击原理:SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查 ...
- 20155207 EXP7 EXP8 EXP9 实验补交
20155207 EXP7 EXP8 EXP9 实验补交 20155207 EXP7 网络欺诈技术防范 20155207 EXP8 Web基础 20155207 <网络对抗> Exp9 W ...
- 20155238 2016-2017-2 《JAVA程序设计》第十周学习总结
教材学习内容总结 # Java计算机网络基础 计算机网络 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统.网络编程就就是编写程序使 ...
- 20155302《网络对抗》Exp6 信息收集与漏洞扫描
20155302<网络对抗>Exp6 信息收集与漏洞扫描 实验内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测 ...
- 2017战略No.2:开始电子化记账
一.懒散的4年 大学毕业后,就没有怎么记账了. 自己花的钱,心里有个大概,但是不能算得很具体. 比如说,2016年,又没有攒几个钱,心里多少有点压抑. 大脑去算账,只能算房租吃饭等金额较大的开销,更多 ...
- tree的使用,显示行号,find命令应用
第1章 linux启动过程 1.开机自检bios 2.mbr引导 3.GRUB 菜单:选择不同的内核 4.加载内核 5.运行init进程 6.读取/etc/inittab运行级别配置文件 7.执行 / ...
- http to https
https://www.cnblogs.com/powertoolsteam/p/http2https.html
- Java关键字 Finally执行与break, continue, return等关键字的关系
长文短总结: 在程序没有在执行到finally之前异常退出的情况下,finally是一定执行的,即在finally之前的return语句将在finally执行之后执行. finally总是在控制转移语 ...
- 了不起的Node.js--之一
在OSX下安装Nodejs 从Node.js官网下载PKG文件,其文件名格式遵循node-v.?.?.?.pkg.若要通过手动编译来进行安装,请确保机器上已安装了XCode,然后根据Linux下的编译 ...