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( ...
随机推荐
- dig命令安装
yum -y install bind-utils Dig是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,MX记录等相关信息的工具 查找yahoo.com的A记录:(此处一定是域而不是 ...
- Microsoft Office Enterprise 2007 在安装过程中出错的解决方法
今天笔者在使用PowerPoint 2007打开一个ppt的内嵌的excel表格时报如下错误: 无法找到 服务器应用程序.源文件.和项目,或返回的未知错误.请重新安装服务程序 然后就先把ppt文件发给 ...
- mysql的sql优化
https://dev.mysql.com/doc/refman/8.0/en/statement-optimization.html 8.2 Optimizing SQL Statements 8. ...
- yii的安装
1.安装composer windows系统直接下载Composer-Setup.exe 运行安装. 2.安装Composer asset plugin composer安装完成后,在一个可通过web ...
- Maven 搭建 SSM框架——Spring+SpringMVC+Mybatis的搭建教程
一:概述 SSM框架在项目开发中经常使用到,相比于SSH框架,它在仅几年的开发中运用的更加广泛. Spring作为一个轻量级的框架,有很多的拓展功能,最主要的我们一般项目使用的就是IOC和AOP.Sp ...
- 前端基础进阶之Promise
前言 Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我 ...
- SQL语句的执行过程
1.语法校验 如果在SQL计划缓存中没有对应的执行计划,服务器首先会对用户请求的SQL语句进行语法效验,如果有语法错误,服务器会结束查询操作,并用返回相应的错误信息给调用它的应用程序. 注意:此时返回 ...
- POJ-1644 To Bet or Not To Bet(概率DP)
To Bet or Not To Bet Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1668 Accepted: 541 D ...
- java 中的继承
继承的概念 继承就是子类继承父类的特征和行为,使得子类具有父类得属性和方法. 继承得关键字:extends 语法格式:<modifier> class <name> [exte ...
- 基于Solr和Zookeeper的分布式搜索方案的配置
1.1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...