题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:

  1. 查询 \(k\) 在区间内的排名
  2. 查询区间内排名为 \(k\) 的值
  3. 修改某一位值上的数值
  4. 查询 \(k\) 在区间内的前驱(前驱定义为严格小于 \(x\),且最大的数,若不存在输出 \(-2147483647\))
  5. 查询 \(k\) 在区间内的后继(后继定义为严格大于 \(x\),且最小的数,若不存在输出\(2147483647\))

Solution

使用分块通过此题。

我们把一个长度为 \(N\) 的序列分成 \(\sqrt N\) 块,每块大小为 \(\sqrt N\),然后维护每个块的有序性。

对于操作 1,直接遍历区间内的块,统计答案即可。时间复杂度 \(O(\sqrt N)\);

对于操作 2,二分答案,用操作 1 检验答案;时间复杂度 \(O(\sqrt N\log N)\)

对于操作 3,暴力修改,排序维护块内顺序,时间复杂度 \(O(\log \sqrt N)\);

对于操作 4、5,等价于查询该数排名 \(+1/-1\) 的数,转化为操作 2。



这样我们便通过了此题。时间复杂度 \(O(N^{\frac 32}\log N)\),空间复杂度 \(T(N)\)。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath> using namespace std; const int MAXN=50010;
const int MAXE=230;
const int MAXA=(int)1e8; int n,m,sq;
int sx,sy,sd; struct point{
int x,y;
friend bool operator<(const point a,const point b){
return a.y<b.y;
}
}a[MAXN];
struct split{
int l,r;
int mininum;
point e[MAXE];
void update(){
sort(e+1,e+(r-l+1)+1);
mininum=e[1].y;
}
void build(point p[MAXN],int L,int R){
if(R>n) R=n;
l=L;r=R;
for(int i=l;i<=r;++i)
e[i-l+1]=p[i];
update();
}
int query(int x){
int left=1,right=(r-l+1),mid,sum=0;
while(left<=right){
mid=(left+right)/2;
if(e[mid].y<x){
sum=mid;
left=mid+1;
}else
right=mid-1;
}
return sum;
}
int que(int left,int right,int x){
int cnt=0;
for(int i=l;i<=r;++i)
if(e[i-l+1].x>=max(l,left)&&e[i-l+1].x<=min(r,right)&&e[i-l+1].y<x) ++cnt;
return cnt;
}
int check(int left,int right,int x){
if(left<=l&&r<=right)
return mininum==x;
for(int i=max(l,left);i<=min(r,right);++i)
if(e[i-l+1].y==x) return 1;
return 0;
}
void change(int x,int d){
for(int i=1;i<=r-l+1;++i)
if(e[i].x==x){
e[i].y=d;
break;
}
update();
}
}s[MAXE];
int len=0; int getnum(int x){
return (x-1)/sq+1;
}
int rank(int l,int r,int x){
int L=getnum(l),R=getnum(r);
int cnt=0;
for(int i=L+1;i<=R-1;++i)
cnt+=s[i].query(x);
cnt+=s[L].que(l,r,x);
if(L!=R) cnt+=s[R].que(l,r,x);
if(!cnt){
for(int i=L;i<=R;++i)
if(s[i].check(l,r,x))
return cnt+1;
return 1;
}
return cnt+1;
}
int find(int l,int r,int x){
int left=0,right=MAXA,mid,s=0;
while(left<=right){
mid=(left+right)/2;
if(rank(l,r,mid)<=x){
s=mid;
left=mid+1;
}else
right=mid-1;
}
return s;
}
void change(int x,int d){
s[getnum(x)].change(x,d);
}
int findupper(int l,int r,int x){
int rk=rank(l,r,x);
if(rk>r-l+1) return 2147483647;
bool flag=(find(l,r,rk)==x);
return find(l,r,rk+flag);
}
int findlower(int l,int r,int x){
int rk=rank(l,r,x);
if(rk<=1) return -2147483647;
return find(l,r,rk-1);
}
inline int read(){
int x=0; char c;
do c=getchar(); while(c<'0'||c>'9');
while(c>='0'&&c<='9')
x=x*10+c-48,c=getchar();
return x;
}
int main(){
n=read();m=read();sq=sqrt(n);
for(int i=1;i<=n;++i)
a[i]=(point){i,read()};
int cnt=0;
while(cnt<n){
s[++len].build(a,cnt+1,cnt+sq);
cnt+=sq;
}
for(int i=1;i<=m;++i){
sd=read();
switch(sd){
case 1:
sx=read();sy=read();sd=read();
int c;
printf("%d\n",c=rank(sx,sy,sd));
break;
case 2:
sx=read();sy=read();sd=read();
printf("%d\n",find(sx,sy,sd));
break;
case 3:
sx=read();sd=read();
change(sx,sd);
break;
case 4:
sx=read();sy=read();sd=read();
printf("%d\n",findlower(sx,sy,sd));
break;
case 5:
sx=read();sy=read();sd=read();
printf("%d\n",findupper(sx,sy,sd));
break;
default:
break;
}
}
}

luogu P3380 【模板】二逼平衡树(分块实现)的更多相关文章

  1. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

  2. 洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  3. 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  4. 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)

    [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...

  5. 【题解】二逼平衡树 [P3380] [BZOJ3196] [Tyvj1730]

    [题解]二逼平衡树 [P3380] [BZOJ3196] [Tyvj1730] 传送门:[模板]二逼平衡树(树套树)\([P3380]\) \([BZOJ3196]\) \([TYVJ1730]\) ...

  6. 【BZOJ 3196】二逼平衡树 线段树套splay 模板题

    我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...

  7. 「luogu3380」【模板】二逼平衡树(树套树)

    「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...

  8. bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...

  9. ZJOI2013 K大数查询 和 LG3380【模板】二逼平衡树(树套树)

    K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c:如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的 ...

  10. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2271  Solved: 935[Submit][Stat ...

随机推荐

  1. golang中Array与Slice

    在golang中有数组和Slice两种数据结构,Slice是基于数组的实现,是长度动态不固定的数据结构,本质上是一个对数组字序列的引用,提供了对数组的轻量级访问.那么在go的函数中以数组或Slice为 ...

  2. sql server之SQL SELECT INTO 语句

    SELECT INTO 语句可用于创建表的备份复件. SELECT INTO 语句 SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中. SELECT INTO 语句常用于创建表 ...

  3. logback配置方法

    logback是一个通用可靠.快速灵活的日志框架,它替代了log4j,和slf4j组成新的日志系统. slf4j是一个日志门面,为其他各种日志框架提供了统一的接口,代码中使用slf4j可以避免对某一种 ...

  4. git远程仓库常用命令

    1.     git  add .               将工作区的文件推到暂存区: 2.    git commit -m " 备注信息"         将暂存区内容提交 ...

  5. Spring入门教程

    Spring新手入门教程,配套下面这两个大神的课程就可以了. 一个是Spring视频教程. 一个是Spring博客教程. https://www.imooc.com/learn/196 http:// ...

  6. Java中一维,二维数组的静态和动态初始化

    今天我们要开始来讲讲Java中的数组,包括一维数组和二维数组的静态初始化和动态初始化 数组概述: 数组可以看成是多个相同类型数据的组合,对这些数据的统一管理; 数组变量属于引用数据类型,数组也可以看成 ...

  7. 使用Git工具批量拉取代码

    公司项目比较多,每天上班第一件事就是拉取代码,cd A 目录 git pull cd .. cd B ...... 一个项目一个项目的拉取,感觉也是很费劲的,那么有没有什么一键操作呢 现在执行一个命令 ...

  8. Jmete压力测试、并发测试的简单方法

    我们的需求场景如下: 服务器硬件:(只有一台) 系统:CentOS 7 WebServer:Tomcat 7.0 Jdk:1.8 CPU:8核 2.9GHz两个 内存:16g 报名应用系统:只需要向外 ...

  9. 这个注册的 IP 网络都不通了,Eureka 注册中心竟然无法踢掉它!

    本文导读: 微服务技术架构选型介绍 k8s 容器化部署架构方案 Eureka 注册中心问题场景 问题解决手段及原理剖析 阅读本文建议先了解: 注册中心基本原理 K8s(Kuberneters)基本概念 ...

  10. eclipse导入别的项目后发现jdk版本不一样,该如何解决呢?

    当我们导入其他人的项目的时候,发现导入的项目的jdk版本与我们使用电脑上的版本不同,该如何解决呢? 选中项目右键 --> Properties --> Build Path --> ...