bzoj3196Tyvj1730二逼平衡树

题意:

维护一个数列,操作:查询k在区间内的排名、查询区间内排名为k的值3、修改某一位上的数值、查询k在区间内的前驱(前驱定义为小于x,且最大的数)、查询k在区间内的后继(后继定义为大于x,且最小的数)

题解:

线段树套treap,我写了一个星期QAQ第一、三个操作直接搞;第二个操作就二分那个值,然后查它在区间内的排名;第四、五个操作就当查询值≤(≥)当前节点就往左(右)走,用一个全局变量记往左(右)走时遍历过的最大(小)值。反思:本弱各种写挂,以前从来把treap的rotate操作写的和splay的rotate操作一样,结果这题如果还这样写,将会异常麻烦,因此不得不用引用型写法,去掉了一个fa数组,异常不习惯。同时第二个操作也很蛋疼,推了很久(实际上是抄了很久),treap也很久没写了,甚至删除节点还出现if(cnt[x]>1){cnt[x]--,sz[x]--; return;}写成if(cnt[x]>0){cnt[x]--,sz[x]--; return;}的错误,调了一整个晚修QAQ。最后交的时候10s,差点TLE。求了一下序列中的最大最小值,在第二个操作做二分时用,省了0.2s;又将线段树的l、r、lc、rc数组去掉,省了0.6s,最后结果是9.2s,还是卡时啊……

yyl大爷:你要多写些题,提高代码能力! orzzzzzzz……

代码:

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#define inc(i,j,k) for(int i=j;i<=k;i++)
#define maxn 2500000
#define maxm 200000
#define INF 0x3fffffff
using namespace std; int v[maxn],rnd[maxn],root[maxm],ch[maxn][],cnt[maxn],sz[maxn],nds,mx,mn,n;
stack <int> pool;
int newnode(){
if(pool.empty())return ++nds;else{int x=pool.top(); pool.pop(); return x;}
}
void delnode(int x){pool.push(x);}
void update(int x){if(! x)return; sz[x]=cnt[x]+sz[ch[x][]]+sz[ch[x][]];}
void rotate(int &x,bool lr){
if(!x)return; int a=ch[x][lr]; ch[x][lr]=ch[a][!lr]; ch[a][!lr]=x; update(x); x=a; update(a);
}
void insert(int &x,int num){
if(!x){int y=newnode(); v[y]=num; rnd[y]=rand(); ch[y][]=ch[y][]=; cnt[y]=sz[y]=; x=y; return;}
if(v[x]==num){cnt[x]++; sz[x]++; return;}
if(num<v[x])insert(ch[x][],num);else insert(ch[x][],num); update(x);
if(ch[x][]&&rnd[ch[x][]]<rnd[x])rotate(x,);
if(ch[x][]&&rnd[ch[x][]]<rnd[x])rotate(x,);
}
void del(int &x,int num){
if(!x)return;
if(v[x]==num){
if(cnt[x]>){cnt[x]--,sz[x]--; return;}
if(ch[x][]*ch[x][]==){delnode(x); x=ch[x][]+ch[x][]; return;} int y=x;
if(rnd[ch[x][]]<rnd[ch[x][]])rotate(x,),del(ch[x][],num);else rotate(x,),del(ch[x][],num);
update(x); return;
}
if(num<v[x])del(ch[x][],num);else del(ch[x][],num); update(x);
}
int rank(int x,int num){
if(!x)return ; if(v[x]==num)return sz[ch[x][]];
if(num<v[x])return rank(ch[x][],num);else return rank(ch[x][],num)+sz[ch[x][]]+cnt[x];
}
int ans;
void before(int x,int num){
if(!x)return; if(num<=v[x])before(ch[x][],num); else ans=max(ans,v[x]),before(ch[x][],num);
}
void after(int x,int num){
if(!x)return; if(num>=v[x])after(ch[x][],num); else ans=min(ans,v[x]),after(ch[x][],num);
}
void add(int x,int l,int r,int pos,int num){
insert(root[x],num); if(l==r)return; int M=(l+r)>>;
if(l<=pos&&pos<=M)add(x<<,l,M,pos,num);
if(M<pos&&pos<=r)add(x<<|,M+,r,pos,num);
}
void change(int x,int l,int r,int pos,int num,int val){
del(root[x],num); insert(root[x],val); if(l==r)return; int M=(l+r)>>;
if(l<=pos&&pos<=M)change(x<<,l,M,pos,num,val); if(M<pos&&pos<=r)change(x<<|,M+,r,pos,num,val);
}
int getrank(int k,int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return rank(root[x],k); int M=(l+r)>>,q=;
if(ql<=M)q+=getrank(k,x<<,l,M,ql,qr); if(M<qr)q+=getrank(k,x<<|,M+,r,ql,qr); return q;
}
int getindex(int k,int ql,int qr){
int L=mn,R=mx;
while(L<=R){
int M=(L+R)>>; int x=getrank(M,,,n,ql,qr);
if(x+<=k)L=M+,ans=M;else R=M-;
}
return ans;
}
void getbefore(int k,int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){before(root[x],k); return;} int M=(l+r)>>;
if(ql<=M)getbefore(k,x<<,l,M,ql,qr); if(M<qr)getbefore(k,x<<|,M+,r,ql,qr);
}
void getafter(int k,int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){after(root[x],k); return;} int M=(l+r)>>;
if(ql<=M)getafter(k,x<<,l,M,ql,qr); if(M<qr)getafter(k,x<<|,M+,r,ql,qr);
}
int val[maxm],m;
int main(){
scanf("%d%d",&n,&m); mx=-; mn=INF;
inc(i,,n)scanf("%d",&val[i]),mx=max(mx,val[i]),mn=min(mn,val[i]),add(,,n,i,val[i]);
inc(i,,m){
int opt,x,y,z; scanf("%d",&opt);
if(opt==)scanf("%d%d%d",&x,&y,&z),printf("%d\n",getrank(z,,,n,x,y)+);
if(opt==)scanf("%d%d%d",&x,&y,&z),printf("%d\n",getindex(z,x,y));
if(opt==)scanf("%d%d",&x,&y),change(,,n,x,val[x],y),val[x]=y,mx=max(mx,y),mn=min(mn,y);
if(opt==)scanf("%d%d%d",&x,&y,&z),ans=-,getbefore(z,,,n,x,y),printf("%d\n",ans);
if(opt==)scanf("%d%d%d",&x,&y,&z),ans=INF,getafter(z,,,n,x,y),printf("%d\n",ans);
}
return ;
}

20160508

bzoj3196Tyvj1730二逼平衡树的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ_3196_二逼平衡树_(树套树,线段树+Treap)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3196 可以处理区间问题的平衡树. 3196: Tyvj 1730 二逼平衡树 Time Lim ...

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

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

  7. [Tyvj 1730] 二逼平衡树

    先来一发题面QwQ [TYVJ1730]二逼平衡树 Time Limit:2 s   Memory Limit:512 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个 ...

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

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

  9. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

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

随机推荐

  1. .Net 对于PDF生成以及各种转换的操作

    前段时间公司的产品,要做一个新功能,签章(就是把需要的数据整理成PDF很标准的文件,然后在盖上我们在服务器上面的章) 然后我就在百度上找了找,发现搞PDF的类库很少,要么就要钱,要么就有水印,破解版的 ...

  2. 色彩空间转换 rgb转ycbcr422/ycbcr422转rgb

    在图像处理过程中通常需要会对图像类型进行互相转换,在此给出两种转换的工程代码. 1.在将ycbCr422转rgb时,通常先将ycbcr422转换成ycbcr444再讲ycbcr444转成rgb 1.1 ...

  3. Spring系列.AOP原理简析

    Spring AOP使用简介 Spring的两大核心功能是IOC和AOP.当我们使用Spring的AOP功能时是很方便的.只需要进行下面的配置即可. @Component @Aspect public ...

  4. PageHelper支持GreenPlum

    greenplum是pivotal在postgresql的基础上修改的一个数据库,语法和postgresql通用.使用PageHelper做分页插件的时候,发现目前没有针对greenplum做支持,但 ...

  5. APP自动化1——Appium+pycharm自动化环境搭建全流程

    1. 安装python3,pycharm,可参考之前写的文档:https://www.cnblogs.com/chenweitoag/p/13154815.html 2. 准备以下必要工具: 基于wi ...

  6. IP地址、计算机名称、MAC地址如何获取

    以下的操作都在“命令提示窗口”中操作. 已知IP,如何获得计算机名称 方法(1): 使用ping -i ip地址 例如已知地址为192.168.1.168. 那么使用ping -i 192.168.1 ...

  7. 东方步进电机马达驱动板CVK系列说明书

    东方步进电机马达驱动板CVK系列说明书

  8. localStorage. sessionStorage、 Cookie不共同点:(面试题)

    ●存储大小的不同: localStorage的大小一般为5M sessionStorage的大小一般为5M cookies的大小一般为4K ●有效期不同: 1.localStorage的有效期为永久有 ...

  9. FIS3安装与编译

    安装 FIS3 npm install -g fis3 -g 安装到全局目录,必须使用全局安装,当全局安装后才能在命令行(cmd或者终端)找到 fis3 命令 安装过程中遇到问题具体请参考 fis#5 ...

  10. SpringCloud 入门(二)

    前文我们介绍了创建注册中心的过程以及配置,接下来我们再简单的创建一个客户端 基本操作和前文一样,不一样的是选择的依赖 然后下一步,修改启动类和配置,结构如下图 修改配置文件application-te ...