先来一发题面QwQ

[TYVJ1730]二逼平衡树

Time Limit:2 s   Memory Limit:512 MB

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

9 6
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

2
4
3
4
9

Hint

n,m<=50000   保证有序序列所有值在任何时刻满足[0,10^8]但是询问的数未必

这题正解似乎是树套树(线段树套平衡树)

然而我用分块大法水过去了233

分块的话思路还是比较明确的,比如对于求排名操作(操作1),对于两端的块我们可以选择直接暴力查询比$key$值小的值的个数,中间的完整块可以选择二分查找($std::lower\_bound$)来得出比$key$小的元素个数,累加起来加上1就是答案了.

求K大的话比较麻烦,要二分第K大的值然后用求排名操作来检验...

修改直接暴力修改不解释

前驱/后继则可以用上面求排名的方式来查找,不同的是对于比$key$小/大的元素不应累加而是求最大/小值.

然后就到了袋马时间~(突然感觉好草率啊QwQ)

GitHub:BlockSearch

 #include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> const int MAXN=;
const int MAXB=;
const int INF=0x7FFFFFFF; int n,m;
int endSize;
int blockNum;
int blockSize;
int data[MAXN];
int block[MAXN][MAXB]; void Initialize();
void FastRead(int&);
void Modify(int,int);
int Kth(int,int,int);
int Rank(int,int,int);
int Predecessor(int,int,int);
int Successor(int,int,int); int main(){
int opt,l,r,num;
Initialize();
for(int i=;i<m;i++){
scanf("%d",&opt);
if(opt==){
FastRead(l);
FastRead(r);
FastRead(num);
printf("%d\n",Rank(l-,r-,num));
}
else if(opt==){
FastRead(l);
FastRead(r);
FastRead(num);
printf("%d\n",Kth(l-,r-,num));
}
else if(opt==){
FastRead(l);
FastRead(num);
Modify(l-,num);
}
else if(opt==){
FastRead(l);
FastRead(r);
FastRead(num);
printf("%d\n",Predecessor(l-,r-,num));
}
else{
FastRead(l);
FastRead(r);
FastRead(num);
printf("%d\n",Successor(l-,r-,num));
}
}
return ;
} inline int Rank(int l,int r,int key){
int lb=l/blockSize;
int rb=r/blockSize;
int ans=;
if(lb==rb){
for(int i=l;i<=r;i++){
if(data[i]<key){
ans++;
}
}
}
else{
for(int i=l;i<(lb+)*blockSize;i++){
if(data[i]<key){
ans++;
}
}
for(int i=rb*blockSize;i<=r;i++){
if(data[i]<key){
ans++;
}
}
for(int i=lb+;i<rb;i++){
ans+=std::lower_bound(block[i],block[i]+blockSize,key)-block[i];
}
}
return ans;
} inline int Kth(int l,int r,int pos){
int L=-;
int R=;
while(R-L>){
int mid=(L+R)>>;
if(Rank(l,r,mid)>pos)
R=mid;
else
L=mid;
}
return R-;
} inline void Modify(int pos,int key){
if(data[pos]==key)
return;
int* thisBlock=block[pos/blockSize];
int old=data[pos];
int size=(pos/blockSize)==blockNum?endSize:blockSize;
data[pos]=key;
pos=std::lower_bound(thisBlock,thisBlock+size,old)-thisBlock;
thisBlock[pos]=key;
std::sort(thisBlock,thisBlock+size);
} inline int Predecessor(int l,int r,int key){
int lb=l/blockSize;
int rb=r/blockSize;
int ans=-INF;
if(lb==rb){
for(int i=l;i<=r;i++){
if(data[i]<key)
ans=std::max(ans,data[i]);
}
}
else{
for(int i=l;i<(lb+)*blockSize;i++){
if(data[i]<key)
ans=std::max(ans,data[i]);
}
for(int i=rb*blockSize;i<=r;i++){
if(data[i]<key)
ans=std::max(ans,data[i]);
}
for(int i=lb+;i<rb;i++){
int pos=std::lower_bound(block[i],block[i]+blockSize,key)-block[i];
if(pos>)
ans=std::max(ans,block[i][pos-]);
}
}
return ans;
} inline int Successor(int l,int r,int key){
int lb=l/blockSize;
int rb=r/blockSize;
int ans=INF;
if(lb==rb){
for(int i=l;i<=r;i++)
if(data[i]>key)
ans=std::min(ans,data[i]);
}
else{
for(int i=l;i<(lb+)*blockSize;i++){
if(data[i]>key)
ans=std::min(ans,data[i]);
}
for(int i=rb*blockSize;i<=r;i++){
if(data[i]>key)
ans=std::min(ans,data[i]);
}
for(int i=lb+;i<rb;i++){
int pos=std::upper_bound(block[i],block[i]+blockSize,key)-block[i];
if(pos<blockSize)
ans=std::min(ans,block[i][pos]);
}
}
return ans;
} void Initialize(){
#ifndef ASC_LOCAL
freopen("psh.in","r",stdin);
freopen("psh.out","w",stdout);
#endif
FastRead(n);
FastRead(m);
blockSize=sqrt(n);
for(int i=;i<n;i++){
FastRead(data[i]);
block[blockNum][endSize]=data[i];
if(++endSize==blockSize){
blockNum++;
endSize=;
}
}
for(int i=;i<blockNum;i++)
std::sort(block[i],block[i]+blockSize);
if(endSize!=)
std::sort(block[blockNum],block[blockNum]+endSize);
} inline void FastRead(int& target){
target=;
register char ch=getchar();
bool neg=false;
while(!isdigit(ch)){
if(ch=='-')
neg=true;
ch=getchar();
}
while(isdigit(ch)){
target=target*+ch-'';
ch=getchar();
}
if(neg)
target=-target;
}

Backup: Block Search

然后图包时间233(拿图至少评论一下吼不吼哇QwQ)

[Tyvj 1730] 二逼平衡树的更多相关文章

  1. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

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

  2. BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

    这道题做法应该很多吧.... 我用了线段树套treap.... -------------------------------------------------------------------- ...

  3. bzoj3196: Tyvj 1730 二逼平衡树 树套树

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...

  4. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  5. bzoj 3196: Tyvj 1730 二逼平衡树

    #include<cstdio> #include<ctime> #include<cstdlib> #include<iostream> #defin ...

  6. 【BZOJ】【3196】Tyvj 1730 二逼平衡树

    树套树 Orz zyf 学(co)习(py)了一下树套树的写法,嗯……就是线段树套平衡树. 具体实现思路就是:外部查询用的都是线段树,查询内部自己调用平衡树的操作. 抄抄代码有助理解= = 八中挂了… ...

  7. 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树

    线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/p ...

  8. [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树

    题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...

  9. BZOJ3196: Tyvj 1730 二逼平衡树

    传送门 主席树的常数蜜汁优越,在BZOJ上跑了rnk1. 做法很简单,主席树套BIT. 1-3做法很简单,第四个和第五个做法转换成前两个就行了. //BZOJ 3196 //by Cydiater / ...

随机推荐

  1. ajax、PHP、session做购物车

    购物车网页代码 1.登录界面login.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  2. scala环境配置+hello world!

    下载地址: http://www.scala-lang.org/download/ 我下载的是zip 配置环境变量 需要jdk支持,jdk的安装配置此处略过 控制台命令 scala -version ...

  3. c++,函数名不要和某个类名相同 (syntax error : missing ';' before identifier....)

    直接上代码: // outside.h class Outside { private: class Inner { public: Inner(Outside& out) : out_(ou ...

  4. 基于Mac制作iPhone铃声教程,iTunes定制铃声

    前言: 网上太多制作方法了,不管是借助第三方软件还是基于iTunes的,不过这些方法都太旧了,有时看起来 ,界面的变化或其他原因,导致很不爽. 正好记录下我最近使用的一种方法: 正文: 一.下载你需要 ...

  5. yii2 入口文件 提示syntax error, unexpected T_OBJECT_OPERATOR

    PHP Version 5.3.3 原因是php的安装版本太低

  6. [leetcode-617-Merge Two Binary Trees]

    Given two binary trees and imagine that when you put one of them to cover the other, some nodes of t ...

  7. 【Android Developers Training】 53. 打印HTML文档

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. Javascript 类继承

    Js继承 JavaScript并不是真正面向对象的语言,是基于对象的,没有类的概念. 要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现 /** 声明一个基础父类 ...

  9. Vijos 1981 跳石头 二分

    描述 一年一度的"跳石头"比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩 ...

  10. PAT-1099(Build A Binary Search Tree)

    题目见这里 分析:分四步进行 1)根据给定的结点情况建二叉树  2)对输入的键值排序(asending) 3)对二叉树中序遍历,同时对应赋key值 4)层次遍历(队列应用) 题目并不困难,但是我误入了 ...