bzoj3196: Tyvj 1730 二逼平衡树 树套树
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196
题目:
3196: Tyvj 1730 二逼平衡树
Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4320  Solved: 1662
[Submit][Status][Discuss]
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]
/**************************************************************
Problem: 3196
User: weeping
Language: C++
Result: Accepted
Time:8668 ms
Memory:83520 kb
****************************************************************/ #include <bits/stdc++.h> using namespace std; #define lc ch[x][0]
#define rc ch[x][1]
#define pr fa[x] inline int read()
{
int a=,f=; char c=getchar();
while (c<''||c>'') {if (c=='-') f=-; c=getchar();}
while (c>=''&&c<='') {a=a*+c-''; c=getchar();}
return a*f;
} const int N = 5e4+;
const int M = 3e6; int n, m, ans, val[N];
int tot, rt[M], ch[M][], fa[M], key[M], sz[M], cnt[M]; inline int wh(int x) { return ch[pr][] == x;} inline void init(int x,int ls,int ky)
{
lc=rc=,sz[x]=cnt[x]=,key[x]=ky,pr=ls;
}
inline void push_up(int x)
{
sz[x]=sz[lc]+sz[rc]+cnt[x];
}
void rotate(int x)
{
int f = fa[x], gf = fa[f], t1 = wh(x);
if( gf ) ch[gf][wh(f)] = x;
fa[x] = gf, ch[f][t1] = ch[x][^t1], fa[ch[f][t1]] = f;
ch[x][t1^] = f, fa[f] = x;
push_up( f ), push_up( x );
}
void splay(int o,int x,int tar)
{
for(;pr!=tar;rotate(x))
if(fa[pr]!=tar) rotate(wh(x)==wh(pr)?pr:x);
if(!tar) rt[o]=x;
}
//void debug(int x)
//{
// if(!x) return;
// if(lc) debug(lc);
// for(int i=1;i<=cnt[x];i++)
// printf("%d ",key[x]);
// if(rc) debug(rc);
//}
void insert(int o,int ky)
{
int x=rt[o],ls=rt[o];
while(x)
{
if(key[x]==ky)
{
sz[x]++,cnt[x]++,splay(o,x,);return;
}
ls=x,x=ch[x][ky>key[x]];
}
init(++tot,ls,ky);
if(!rt[o]) { rt[o]=tot; return ;}
x=ls, ch[x][ky>key[x]]=tot;
splay(o,tot,);
}
int find(int o,int ky)
{
int x=rt[o];
//debug(rt[o]);printf("\n");
while(x)
{
if(key[x]==ky) break;
x=ch[x][ky>key[x]];
}
if(x) splay(o,x,);
else x=-;
return x;
}
void merge(int o,int x,int y)
{
if(!x){rt[o]=y;return;}
if(!y) {rt[o]=x;return;}
while(rc) x=rc;
splay(o,x,);
rc=y,fa[y]=x;
push_up(x);
}
void del(int o,int ky)
{
if(!rt[o]) return;
int x=find(o,ky);
if(cnt[x]>) {cnt[x]--,sz[x]--;return;}
int tl=lc,tr=rc;
fa[tl]=fa[tr]=cnt[x]=sz[x]=lc=rc=;
if(sz[x]==) {rt[o]=;return;}
merge(o,tl,tr);
}
void getpre(int x,int ky)
{
if(!x)return;
if(key[x]<ky) ans=max(ans,key[x]),getpre(rc,ky);
else getpre(lc,ky);
}
void getnext(int x,int ky)
{
if(!x) return;
if(key[x]>ky) ans=min(ans,key[x]),getnext(lc,ky);
else getnext(rc,ky);
}
int getsz(int o,int ky)
{
int x=rt[o],ret=;
while(x)
{
if(key[x]==ky) return ret+sz[lc];
if(key[x]<ky) ret+=sz[lc]+cnt[x],x=rc;
else x=lc;
}
return ret;
} void update(int o,int l,int r,int pos,int x,int op=)
{
if(op) del(o,val[pos]);
insert(o,x);
//debug(rt[o]);printf("\n");
if(l==r) return ;
int mid=l+r>>;
if(pos<=mid) update(o<<,l,mid,pos,x,op);
else update(o<<|,mid+,r,pos,x,op);
}
int get_rank(int o,int l,int r,int nl,int nr,int ky)
{
//debug(rt[o]);printf("\n");
if(nl==l&&r==nr) return getsz(o,ky);
int mid=l+r>>;
if(nr<=mid) return get_rank(o<<,l,mid,nl,nr,ky);
else if(nl>mid) return get_rank(o<<|,mid+,r,nl,nr,ky);
return get_rank(o<<,l,mid,nl,mid,ky)+get_rank(o<<|,mid+,r,mid+,nr,ky);
}
void get_pre(int o,int l,int r,int nl,int nr,int ky)
{
if(nl==l&&r==nr) return getpre(rt[o],ky);
int mid=l+r>>;
if(nr<=mid) return get_pre(o<<,l,mid,nl,nr,ky);
else if(nl>mid) return get_pre(o<<|,mid+,r,nl,nr,ky);
get_pre(o<<,l,mid,nl,mid,ky),get_pre(o<<|,mid+,r,mid+,nr,ky);
}
void get_next(int o,int l,int r,int nl,int nr,int ky)
{
//debug(rt[o]);printf("\n");
if(nl==l&&r==nr) return getnext(rt[o],ky);
int mid=l+r>>;
if(nr<=mid) return get_next(o<<,l,mid,nl,nr,ky);
else if(nl>mid) return get_next(o<<|,mid+,r,nl,nr,ky);
get_next(o<<,l,mid,nl,mid,ky),get_next(o<<|,mid+,r,mid+,nr,ky);
}
int get_kth(int nl,int nr,int k)
{
int l=,r=1e8+,ans=;
while(l<=r)
{
int mid=l+r>>;
if(get_rank(,,n,nl,nr,mid)+<=k) l=mid+,ans=mid;
else r=mid-;
}
return ans;
}
int main(void)
{
n=read(),m=read();
for(int i=;i<=n;i++)
val[i]=read(),update(,,n,i,val[i]);
int op,l,r,x;
while(m--)
{
op=read(),l=read(),r=read();
if(op==)
{update(,,n,l,r,);val[l]=r;continue;}
x=read();
if(op==)
ans=get_rank(,,n,l,r,x)+;
else if(op==)
ans=get_kth(l,r,x);
else if(op==)
ans=-0x3f3f3f3f,get_pre(,,n,l,r,x);
else
ans=0x3f3f3f3f,get_next(,,n,l,r,x);
printf("%d\n",ans);
}
}
bzoj3196: Tyvj 1730 二逼平衡树 树套树的更多相关文章
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
		
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1807 Solved: 772[Submit][Stat ...
 - bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)
		
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ...
 - [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
		
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...
 - 【分块】bzoj3196 Tyvj 1730 二逼平衡树
		
分块 或 树套树. 在每个块中维护一个有序表,查询时各种二分,全都是分块的经典操作,就不详细说了. 块的大小定为sqrt(n*log2(n))比较快. #include<cstdio> # ...
 - 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树
		
线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/p ...
 - BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay
		
传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...
 - BZOJ3196: Tyvj 1730 二逼平衡树
		
传送门 主席树的常数蜜汁优越,在BZOJ上跑了rnk1. 做法很简单,主席树套BIT. 1-3做法很简单,第四个和第五个做法转换成前两个就行了. //BZOJ 3196 //by Cydiater / ...
 - [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)
		
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
 - bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】
		
四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...
 
随机推荐
- Xcode快速排错
			
EXTENDS:http://blog.csdn.net/guo_hongjun1611/article/details/8063009 1,模拟器运行完全没问题,真机运行失败. 有时候我们在模拟器上 ...
 - iOS - 开源框架、项目和学习资料汇总(UI篇)
			
上下拉刷新控件 1. MJRefresh --仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明.(推荐)2. SV ...
 - yii---判断POST请求
			
我们在进行数据的提交的时候,很多时候会判断请求状态来进行不同的选择.常见的就是判断POST以及GET的请求方式,下面是YII判断POST请求的代码示例: public function actionP ...
 - thinkphp结合layui上传视频
			
JS示例: <script type="text/javascript"> layui.use(['form', 'layedit','element', 'layda ...
 - BAT等大厂已开源的70个实用工具盘点(附下载地址)
			
前面的一篇文章<微软.谷歌.亚马逊.Facebook等硅谷大厂91个开源软件盘点(附下载地址)>列举了国外8个互联网公司(包括微软.Google.亚马逊.IBM.Facebook.Twit ...
 - ubuntu16.04下安装pangolin
			
安装教程,具体可以参考github上pangolin的安装文档 https://github.com/stevenlovegrove/Pangolin 首先要安装pangolin的各种依赖项 Glew ...
 - CodeForces - 779D String Game 常规二分
			
题意:给你两个串,S2是S1 的一个子串(可以不连续).给你一个s1字符下标的一个排列,按照这个数列删数,问你最多删到第几个时S2仍是S1 的一个子串. 题解:二分删掉的数.判定函数很好写和单调性也可 ...
 - SET NAMES
			
High Performance MySQL, Third Editionby Baron Schwartz, Peter Zaitsev, and Vadim Tkachenko Settings ...
 - Json模块dumps、loads、dump、load函数介绍
			
转自:http://blog.csdn.net/mr_evanchen/article/details/77879967 Json模块dumps.loads.dump.load函数介绍 1.json. ...
 - MYSQL 命令行显示乱码 解决方案
			
中文乱码是因为编码集不支持,所以要改变编码 先查看下设置的编码 使用如下命令 show variables like 'character%'; 在 mysql.conf (Ubuntu mysql5 ...