http://www.lydsy.com/JudgeOnline/problem.php?id=3196 (题目链接)

题意

  1.查询k在区间内的排名;2.查询区间内排名为k的值;3.修改某一位值上的数值;4.查询k在区间内的前驱(前驱定义为小于x,且最大的数);5.查询k在区间内的后继(后继定义为大于x,且最小的数)

Solution

  修改不好搞,主席树套树状数组空间炸,最好的选择→_→:线段树套treap。

  对于操作2,我们二分找到一个排名大于$k$的最小的数,然后查询这个数的前驱即可。

细节

  查询前驱和后继的时候要特判一下没有找到的情况。

代码

// bzoj3196
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std; const int maxn=50010;
int a[maxn],n,m;
struct node {
int son[2],l,r,w,val,rnd,size,tree;
int& operator [] (int x) {return son[x];}
}; namespace Treap {
int sz;node tr[maxn*50];
void pushup(int x) {
tr[x].size=tr[tr[x][0]].size+tr[tr[x][1]].size+tr[x].w;
}
void rotate(int &x,int p) {
int y=tr[x][p];
tr[x][p]=tr[y][p^1];tr[y][p^1]=x;x=y;
pushup(tr[y][p^1]);pushup(y);
}
void insert(int &k,int x) {
if (!k) {tr[k=++sz].val=x;tr[k].rnd=rand();tr[k].size=tr[k].w=1;return;}
int p=x>tr[k].val;tr[k].size++;
if (x==tr[k].val) {tr[k].w++;return;}
insert(tr[k][p],x);
if (tr[tr[k][p]].rnd>tr[k].rnd) rotate(k,p);
}
void erase(int &k,int x) {
if (!k) return;
if (tr[k].val==x) {
if (tr[k].w>1) {tr[k].w--;tr[k].size--;return;}
if (tr[k][0]*tr[k][1]==0) k=tr[k][0]+tr[k][1];
else rotate(k,tr[tr[k][1]].rnd>tr[tr[k][0]].rnd),erase(k,x);
}
else tr[k].size--,erase(tr[k][x>tr[k].val],x);
}
int rank(int k,int x) {
if (!k) return 0;
if (x<=tr[k].val) return rank(tr[k][0],x);
else return rank(tr[k][1],x)+tr[tr[k][0]].size+tr[k].w;
}
int find(int k,int x) {
if (!k) return -1;
if (tr[tr[k][0]].size<x && x<=tr[tr[k][0]].size+tr[k].w) return tr[k].val;
else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);
else return find(tr[k][1],x-tr[tr[k][0]].size-tr[k].w);
}
int pref(int k,int x) {return find(k,rank(k,x));}
int suff(int k,int x) {return find(k,rank(k,x+1)+1);}
} namespace Segtree {
node tr[maxn<<2];
void build(int k,int s,int t) {
tr[k].l=s;tr[k].r=t;
for (int i=s;i<=t;i++) Treap::insert(tr[k].tree,a[i]);
if (s==t) return;
int mid=(s+t)>>1;
build(k<<1,s,mid);build(k<<1|1,mid+1,t);
}
void modify(int k,int p,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
Treap::erase(tr[k].tree,a[p]);
Treap::insert(tr[k].tree,val);
if (l==r) return;
if (p<=mid) modify(k<<1,p,val);
else modify(k<<1|1,p,val);
}
int rank(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) return Treap::rank(tr[k].tree,val);
if (t<=mid) return rank(k<<1,s,t,val);
else if (s>mid) return rank(k<<1|1,s,t,val);
else return rank(k<<1,s,mid,val)+rank(k<<1|1,mid+1,t,val);
}
int pref(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) {
int tmp=Treap::pref(tr[k].tree,val);
return tmp==-1 ? -inf : tmp;
}
if (t<=mid) return pref(k<<1,s,t,val);
else if (s>mid) return pref(k<<1|1,s,t,val);
else return max(pref(k<<1,s,mid,val),pref(k<<1|1,mid+1,t,val));
}
int suff(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (s==l && t==r) {
int tmp=Treap::suff(tr[k].tree,val);
return tmp==-1 ? inf : tmp;
}
if (t<=mid) return suff(k<<1,s,t,val);
else if (s>mid) return suff(k<<1|1,s,t,val);
else return min(suff(k<<1,s,mid,val),suff(k<<1|1,mid+1,t,val));
}
int find(int s,int t,int k) {
int l=0,r=1e8,res;
while (l<=r) {
int mid=(l+r)>>1;
if (rank(1,s,t,mid)>=k) r=mid-1,res=mid;
else l=mid+1;
}
return pref(1,s,t,res);
}
}
using namespace Segtree; int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
for (int op,x,y,k,i=1;i<=m;i++) {
scanf("%d%d%d",&op,&x,&y);
if (op==1) scanf("%d",&k),printf("%d\n",rank(1,x,y,k)+1);
if (op==2) scanf("%d",&k),printf("%d\n",find(x,y,k));
if (op==4) scanf("%d",&k),printf("%d\n",pref(1,x,y,k));
if (op==5) scanf("%d",&k),printf("%d\n",suff(1,x,y,k));
if (op==3) modify(1,x,y),a[x]=y;
}
return 0;
}

【bzoj3196】 Tyvj1730—二逼平衡树的更多相关文章

  1. BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】

    BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...

  2. [BZOJ3196][Tyvj1730]二逼平衡树

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

  3. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  4. bzoj3196 [TYVJ1730]二逼平衡树 树套树 线段树套替罪羊树

    人傻自带大常数 二分的可行性证明: 贴近他的正确答案不会被当作次优解删掉,因为,若二分在他右边发生,那么二分一定会把左边作为优解,左边同理,所以他一定是被扣掉的所以最后一个小于等于一定是正确答案 #i ...

  5. bzoj3196:Tyvj1730二逼平衡树

    传送门 暴力啊,直接树套树上啊 线段树套splay,卡卡常就直接A了 代码: #include<cstdio> #include<iostream> #include<a ...

  6. [BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)

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

  7. 【BZOJ3196】二逼平衡树(树状数组,线段树)

    [BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...

  8. [TYVJ1730]二逼平衡树

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

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

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

随机推荐

  1. SQL_sql语言的学习

    关系数据库SQL sql基本功能 SQLde 基本概念 主要知识点 1.外模式包含若干视图和部分基本表 2.模式包含若干基本表 3.内模式包含若干存储文件 4操作对象 基本表:本身独立存在的表,一个关 ...

  2. 一个有趣的异步时序逻辑电路设计实例 ——MFM调制模块设计笔记

    本文从本人的163博客搬迁至此. MFM是改进型频率调制的缩写,其本质是一种非归零码,是用于磁介质硬盘存储的一种调制方式.调制规则有两句话,即两个翻转条件: 1.为1的码元在每个码元的正中进行一次翻转 ...

  3. 20155226《网络攻防》 Exp5 MSF基础应用

    20155226<网络攻防> Exp5 MSF基础应用 基础问题回答 1.用自己的话解释什么是exploit,payload,encode? exploit : Exploit的英文意思就 ...

  4. 20155339 Exp5 MSF基础应用

    20155339 Exp5 MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode. 答: exploit是通过自己选择的漏洞和载荷进行攻击的一个过程. pay ...

  5. Hibernate一对多关联关系保存时的探究

    在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功.    因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备         这里有一点提前 ...

  6. Compensating-Transaction模式

    在应用中,会将一系列相关的操作定义为一个连续的操作,当其中一个或者多个步骤失败的时候,Compensating-Transaction模式会重置(回滚)这个连续的操作.在云应用中,这些需要保证一致性的 ...

  7. 【第八课】php-fpm.conf配置文件解析

    在discuz论坛的nginx配置文件当中,我们可以看到有一段php解析的配置,如下: location ~ \.php$ { try_files $uri = 404; fastcgi_pass 1 ...

  8. Selenium-ActionChainsApi接口详解

    ActionChains 有时候我们在通过Selenium做UI自动化的时候,明明能够在DOM树内看到这个元素,但是我在通过driver click.sendkey的时候,就是点击不到或无法输入字符串 ...

  9. 设计模式 笔记 单例模式 Singleton

    //---------------------------15/04/09---------------------------- //Singleton 单例模式-----对象创建型模式 /* 1: ...

  10. if 判断文件

    #!/bin/sh#判断文件存在,判断是否为文件夹等testPath="/Volumes/MacBookProHD/Mr.Wen/08 shell命令"testFile=" ...