【BZOJ3196】Tyvj 1730 二逼平衡树
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)
Input
第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继
Output
对于操作1,2,4,5各输出一行,表示查询结果
Sample Input
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5
Sample Output
4
3
4
9
HINT
1.n和m的数据范围:n,m<=50000
2.序列中每个数的数据范围:[0,1e8]
1 #include<cstdio> 2 #include<cstdlib> 3 #include<iostream> 4 using namespace std; 5 const int inf=100000000,N=3000001,M=200001; 6 int num[N],rnd[N],size[N],ls[N],rs[N],root[M],w[N],a[M]; 7 int sz,n,m,opt,l,r; 8 void updata(int k){size[k]=size[ls[k]]+size[rs[k]]+w[k];} 9 void rturn(int &k){int t=ls[k];ls[k]=rs[t];rs[t]=k;size[t]=size[k];updata(k);k=t;} 10 void lturn(int &k){int t=rs[k];rs[k]=ls[t];ls[t]=k;size[t]=size[k];updata(k);k=t;} 11 void insert(int &k,int x){ 12 if (!k){ 13 k=++sz;num[k]=x;rnd[k]=rand();size[k]=w[k]=1;return; 14 } 15 size[k]++; 16 if (x==num[k]) {w[k]++;return;} 17 if (x<num[k]) {insert(ls[k],x);if (rnd[ls[k]]<rnd[k]) rturn(k);} 18 if (x>num[k]) {insert(rs[k],x);if (rnd[rs[k]]<rnd[k]) lturn(k);} 19 } 20 21 void del(int &k,int x){ 22 if (!k) return; 23 if (num[k]==x){ 24 if (w[k]>1){w[k]--;size[k]--;return;}//就是这里,不知道为什么不是在前面直接size[k]-- 25 if(ls[k]*rs[k]==0){k=ls[k]+rs[k]; return;} 26 if (rnd[ls[k]]<rnd[rs[k]])rturn(k),del(k,x); 27 else lturn(k),del(k,x); 28 } 29 else if (num[k]>x) del(ls[k],x),size[k]--;else del(rs[k],x),size[k]--; 30 } 31 32 void change(int pos,int x){ 33 int k=1,l=1,r=n,mid=(l+r)>>1; 34 while (l!=r){ 35 mid=(l+r)>>1; 36 del(root[k],a[pos]); 37 insert(root[k],x); 38 if (mid>=pos)k=k<<1,r=mid; 39 else k=k<<1|1,l=mid+1; 40 } 41 mid=(l+r)>>1; 42 del(root[k],a[pos]); 43 insert(root[k],x); 44 } 45 46 int solve_rank(int k,int x){ 47 if (!k) return 0; 48 int l=ls[k],r=rs[k]; 49 if (num[k]==x) return size[l]; 50 else if (num[k]>x) return solve_rank(l,x); 51 else return solve_rank(r,x)+size[l]+w[k]; 52 } 53 54 int get_rank(int k,int l,int r,int L,int R,int x){ 55 if (l==L&&r==R) return (solve_rank(root[k],x)); 56 int mid=(l+r)>>1; 57 if (R<=mid) return get_rank(k<<1,l,mid,L,R,x); 58 else if (L>mid) return get_rank(k<<1|1,mid+1,r,L,R,x); 59 else return get_rank(k<<1,l,mid,L,mid,x)+get_rank(k<<1|1,mid+1,r,mid+1,R,x); 60 } 61 62 void build(int x,int y){ 63 int l=1,r=n,k=1,mid=(l+r)>>1; 64 while(l!=r){ 65 insert(root[k],y); 66 if (mid>=x) r=mid,mid=(l+r)>>1,k=k<<1; 67 else l=mid+1,mid=(l+r)>>1,k=k<<1|1; 68 } 69 insert(root[k],y); 70 } 71 72 int get_num(int x,int y,int z){ 73 int l=1,r=inf,ans; 74 while (l<=r){ 75 int mid=(l+r)>>1; 76 int tmp=get_rank(1,1,n,x,y,mid); 77 if (tmp<=z) ans=mid,l=mid+1;//因为有重复的数字,tmp偏小 78 else r=mid-1; 79 } 80 return ans; 81 } 82 83 int solve_pre(int k,int x){ 84 int l=ls[k],r=rs[k]; 85 if (!k) return 0; 86 if (num[k]<x) return max(num[k],solve_pre(r,x));//这里不要顺手打上= 87 else return solve_pre(l,x); 88 } 89 90 int get_pre(int k,int l,int r,int L,int R,int x){ 91 if (l==L&&r==R) return (solve_pre(root[k],x)); 92 int mid=(l+r)>>1; 93 if (R<=mid) return get_pre(k<<1,l,mid,L,R,x); 94 else if (L>mid) return get_pre(k<<1|1,mid+1,r,L,R,x); 95 else return max(get_pre(k<<1,l,mid,L,mid,x),get_pre(k<<1|1,mid+1,r,mid+1,R,x)); 96 } 97 98 int solve_after(int k,int x){ 99 int l=ls[k],r=rs[k]; 100 if (!k) return inf; 101 if (num[k]>x) return min(num[k],solve_after(l,x));//这里不要顺手打上=*2 102 else return solve_after(r,x); 103 } 104 105 int get_after(int k,int l,int r,int L,int R,int x){ 106 if (l==L&&r==R) return (solve_after(root[k],x)); 107 int mid=(l+r)>>1; 108 if (R<=mid) return get_after(k<<1,l,mid,L,R,x); 109 else if (L>mid) return get_after(k<<1|1,mid+1,r,L,R,x); 110 else return min(get_after(k<<1|1,mid+1,r,mid+1,R,x),get_after(k<<1,l,mid,L,mid,x)); 111 } 112 113 int main(){ 114 freopen("sj.txt","r",stdin); 115 freopen("me.txt","w",stdout); 116 int k; 117 scanf("%d%d",&n,&m); 118 for (int i=1;i<=n;i++){scanf("%d",&a[i]);build(i,a[i]);} 119 for (int i=1;i<=m;i++){ 120 scanf("%d%d%d",&opt,&l,&r); 121 if (opt!=3)scanf("%d",&k); 122 switch(opt){ 123 case 1:printf("%d\n",get_rank(1,1,n,l,r,k)+1);break; 124 case 2:printf("%d\n",get_num(l,r,k-1));break; 125 case 3:change(l,r);a[l]=r;break; 126 case 4:printf("%d\n",get_pre(1,1,n,l,r,k));break; 127 case 5:printf("%d\n",get_after(1,1,n,l,r,k));break; 128 } 129 } 130 }
转载于:https://www.cnblogs.com/wuminyan/p/5152475.html
【BZOJ3196】Tyvj 1730 二逼平衡树相关推荐
- Bzoj 3196 Tyvj 1730 二逼平衡树
3196: Tyvj 1730 二逼平衡树 >原题链接< Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...
- bzoj 3196/tyvj p1730 二逼平衡树
原题链接:http://www.tyvj.cn/p/1730 树套树... 如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #incl ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2271 Solved: 935 [Submit][St ...
- 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)
[模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...
- BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)
我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...
- [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】
题目地址 [洛谷传送门] 题目大意 区间查询k的排名,查找k排名的数,单点修改,区间前驱,区间后继. 感想 真的第一次写树套树,整个人都不对了.重构代码2次,发现样例都过不了,splay直接爆炸,可能 ...
- 【BZOJ3196】【Tyvj1730】二逼平衡树,第一次的树套树(线段树+splay)
传送门1 传送门2 写在前面:创造迄今最长的正常代码的记录 思路:个人感觉这个树套树就是对线段树的每个区间建一棵splay来维护,最初觉得这个方法会爆T爆M--(实际上真的可能会爆).对于5个操作,我 ...
- 二逼平衡树——树套树(线段树套Splay平衡树)
题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...
- luogu P3380 【模板】二逼平衡树(树套树)
恭喜你 以分块的姿势通过了此题 #include<cmath> #include<cstdio> #include<algorithm> #define inf ( ...
最新文章
- MYSQL体系结构-来自期刊
- 一些常用工具地址,随时更新中~
- tabcontainer控件太长_AjaxControlToolKit--TabContainer控件的介绍收藏[摘录]
- 可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值
- MapReduce 论文翻译
- Checkpoint IC_WEBCLIENT_PROCESS_CNTRL_DBG
- 静态创意和动态创意_我在22岁时学到的关于创意指导的知识
- 配置mysql为主主复制步骤
- linux set权限,Linux 特殊权限set_uid(示例代码)
- 微信第三方扫描登录 java源代码_微信开放平台基于网站应用授权登录源码(java)...
- 计算机视觉论文-2021-07-08
- 一些比较恶心的代码片段
- java post 403_求助啊。。。。。。给服务器POST JSON报403
- Jmeter发送get请求
- php libev扩展使用
- 基于WFST的语音识别解码器
- IT运维服务体系建设思路
- 计算机专业的文献综述题目,计算机专业文献综述格式及要求
- 新构造运动名词解释_新构造运动
- [转]ubuntu常用软件
热门文章
- C#学习笔记(C#与C++的差异)001
- 谁来谈谈Google Earth的核心技术和架构?(转)
- 数据统计分析中的几点
- linux命令(51):set 指定行,直接替换并修改文件
- 程序员的魔法——用Masking GAN让100,000人都露出灿烂笑容
- 【POI xls】解析xls遇到的问题
- CISSP考前总复习
- c语言外部中断th0,帮忙看看void int0() interrupt 1 //采用中断0 控制节拍 { TH0=0xd8; TL0=0xef; n--; } 啥意思...
- Struts2-表单验证的两种方式
- 漫谈递归:从斐波那契开始了解尾递归