题目描述

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

  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. 【新】mybatis中大于等于小于等于的两种常用写法

    mybatis中大于等于小于等于的写法 原符号 < <= > >= & ' " 替换符号 < <= > >= & &a ...

  2. ubuntu上vritualbox为系统分配硬盘空间

    VBoxManage是virtualbox 在ubuntu上提供的管理virtualbox的命令行命令 VBoxManage modifyhd windowsDevEnv --resize VBoxM ...

  3. 具有注册、登陆以及后台管理功能的web开发

    设计一个带有注册.登陆.后台用户管理的网站 使用(Html+Css+JavaScript+Jsp+Servlet+JDBC+JSTL+EL) 工具:Eclipse(NetBeans).Mysql8.0 ...

  4. jsp学习:jsp学习阶段性总结2019.9.21

    Jsp学习 jsp语法格式: 脚本程序:<% 代码片段 %> jsp声明:<%! declaration; [ declaration; ]+ ... %> 表达式:<% ...

  5. MOOC C++笔记(四):运算符重载

    第四周:运算符重载 基本概念 运算符重载,就是对已有的运算符(C++中预定义的运算符)赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为. 运算符重载的目的是:扩展C++中提供的运算 ...

  6. python小基础

    1.计算机基础知识 中央处理器 CPU 人的大脑 内存 缓存数据 临时记忆 硬盘 储存数据 永久记忆 什么是操作系统 ? 控制计算机工作的流程 什么是应用程序? 安装在操作系统之上的软件 2.pyth ...

  7. [VB.NET Tips]程序的启动和终止

    当执行一个VB.NET应用程序时,CLR会把IL翻译成x86指令,并且寻找一个名为Main的方法. 并从该方法开始执行程序.Main方法也称为程序的"入口"(entry point ...

  8. 从零开始入门 K8s | 应用编排与管理(酒祝)

    一.需求来源 背景问题 首先来看一下背景问题.如下图所示:如果我们直接管理集群中所有的 Pod,应用 A.B.C 的 Pod,其实是散乱地分布在集群中. 现在有以下的问题: 首先,如何保证集群内可用 ...

  9. Android Studio [登陆界面]

    EdittextActivity.class package com.xdw.a122; import android.support.v7.app.AppCompatActivity; import ...

  10. Spring boot 官网学习笔记 - Auto-configuration(@SpringBootApplication、@EnableAutoConfiguration、@Configuration)

    Spring Boot auto-configuration attempts to automatically configure your Spring application based on ...