bzoj3196 二逼平衡树
平衡树系列最后一题
坑啊

10s时间限制跑了9764ms。。。还是要学一学bit套主席树啦。。。
经典的线段树套treap。。。至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了旋转 WOC)
自认为treap写的挺好看的(欢迎来喷)
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define rre(i,r,l) for(int i=(r);i>=(l);i--)
#define re(i,l,r) for(int i=(l);i<=(r);i++)
#define Clear(a,b) memset(a,b,sizeof(a))
#define inout(x) printf("%d",(x))
#define douin(x) scanf("%lf",&x)
#define strin(x) scanf("%s",(x))
#define LLin(x) scanf("%lld",&x)
#define op operator
#define CSC main
typedef unsigned long long ULL;
typedef const int cint;
typedef long long LL;
using namespace std;
cint inf=;
void inin(int &ret)
{
ret=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=;ch=getchar();}
while(ch>=''&&ch<='')ret*=,ret+=ch-'',ch=getchar();
ret=f?-ret:ret;
}
int ch[][],c[],s[],rr[],w[],ed;
struct segtree
{
int l,r,root;
segtree(){root=;}
void maintain(int k){if(k)s[k]=c[k]+s[ch[k][]]+s[ch[k][]];}
void rotate(int &k,int d)
{
int p=ch[k][d^];
ch[k][d^]=ch[p][d];
ch[p][d]=k;s[p]=s[k];
maintain(k),k=p;
}
private:
void add(int &k,const int &x)
{
if(!k)
{
k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=;ch[k][]=ch[k][]=;
return ;
}s[k]++;
if(x==w[k]){c[k]++;return ;}
int d=x>w[k];add(ch[k][d],x);
if(rr[ch[k][d]]<rr[k])rotate(k,d^);
}
bool del(int &k,const int &x)
{
if(!k)return ;
if(x==w[k])
{
if(c[k]>){c[k]--,s[k]--;return ;}
if(!ch[k][]){k=ch[k][];return ;}
if(!ch[k][]){k=ch[k][];return ;}
if(rr[ch[k][]]<rr[ch[k][]])rotate(k,);
else rotate(k,);
return del(k,x);
}
int d=x>w[k];
if(del(ch[k][d],x))
{
s[k]--;
return ;
}
else return ;
}
int findrank(int k,const int &x)
{
if(!k)return ;
int pp=(ch[k][]?s[ch[k][]]:);
if(x==w[k])return pp;
if(x>w[k])return pp+c[k]+findrank(ch[k][],x);
return findrank(ch[k][],x);
}
int findwei(int k,const int &x)
{
if(!k)return ;
int pp=(ch[k][]?s[ch[k][]]:);
if(x<=pp)return findwei(ch[k][],x);
if(x>pp+c[k])return findwei(ch[k][],x-pp-c[k]);
return w[k]; }
void findqian(int k,const int &x,int &ans)
{
if(!k)return ;
if(x>w[k])ans=w[k],findqian(ch[k][],x,ans);
else findqian(ch[k][],x,ans);
}
void findhou(int k,const int &x,int &ans)
{
if(!k)return ;
if(x<w[k])ans=w[k],findhou(ch[k][],x,ans);
else findhou(ch[k][],x,ans);
}
public:
void add(int x){add(root,x);}
void del(int x){del(root,x);}
int findrank(int x){return findrank(root,x);}
int findwei(int x){return findwei(root,x);}
int findqian(int x)
{
int ans=;findqian(root,x,ans);
return ans;
}
int findhou(int x)
{
int ans=;findhou(root,x,ans);
return !ans?inf:ans;
}
}t[];
int qi[];
void build(int k,int l,int r,int x)
{
t[k].l=l,t[k].r=r,t[k].add(qi[x]);
if(l==r)return ;int mid=(l+r)>>;
if(x<=mid)build(k<<,l,mid,x);
else build(k<<|,mid+,r,x);
}
int findrank(int k,int l,int r,int x)
{
if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x);
int mid=(t[k].l+t[k].r)>>,p1=k<<,p2=p1|;
if(r<=mid)return findrank(p1,l,r,x);
if(l>mid)return findrank(p2,l,r,x);
return findrank(p1,l,r,x)+findrank(p2,l,r,x);
}
int findqian(int k,int l,int r,int x)
{
if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x);
int mid=(t[k].l+t[k].r)>>,p1=k<<,p2=p1|;
if(r<=mid)return findqian(p1,l,r,x);
if(l>mid)return findqian(p2,l,r,x);
return max(findqian(p1,l,r,x),findqian(p2,l,r,x));
}
int findhou(int k,int l,int r,int x)
{
if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x);
int mid=(t[k].l+t[k].r)>>,p1=k<<,p2=p1|;
if(r<=mid)return findhou(p1,l,r,x);
if(l>mid)return findhou(p2,l,r,x);
return min(findhou(p1,l,r,x),findhou(p2,l,r,x));
}
int findwei(int l,int r,int x)
{
int ll=,rr=inf,mid,ans;
while(ll<=rr)
{
mid=(ll+rr)>>;
int rank=findrank(,l,r,mid)+;
if(rank<=x)ans=mid,ll=mid+;else rr=mid-;
}
return findqian(,l,r,ans+);
}
void change(int k,int x,int w)
{
t[k].del(qi[x]),t[k].add(w);
if(t[k].l==t[k].r)return ;
int mid=(t[k].l+t[k].r)>>;
if(x<=mid)change(k<<,x,w);
else change(k<<|,x,w);
}
int n,m;
int CSC()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
inin(n),inin(m);
re(i,,n)inin(qi[i]);
re(i,,n)build(,,n,i);
re(i,,m)
{
int opt,q,ww,e;
inin(opt);
if(opt==)
{
inin(q),inin(ww),inin(e);
printf("%d\n",findrank(,q,ww,e)+);
}
else if(opt==)
{
inin(q),inin(ww),inin(e);
printf("%d\n",findwei(q,ww,e));
}
else if(opt==)
{
inin(q),inin(ww);
change(,q,ww);qi[q]=ww;
}
else if(opt==)
{
inin(q),inin(ww),inin(e);
printf("%d\n",findqian(,q,ww,e));
}
else
{
inin(q),inin(ww),inin(e);int ret=findhou(,q,ww,e);
// printf("%d\n",ret==inf?0:ret);
printf("%d\n",ret);
}
}
return ;
}
bzoj3196 二逼平衡树的更多相关文章
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- bzoj3196 二逼平衡树 树状数组套线段树
题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...
- bzoj3196 二逼平衡树 树套树(线段树套Treap)
Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4697 Solved: 1798[Submit][Status][D ...
- BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)
我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...
- [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]
题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...
- BZOJ3196 二逼平衡树 【线段树套平衡树】
题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱 ...
- BZOJ3196——二逼平衡树
1.题目大意:给你一个序列,有5种操作,都有什么呢... 1> 区间第k小 这个直接用二分+树套树做 2> 区间小于k的有多少 这个直接用树套树做 3> 单点修改 这个直接用树套树做 ...
- luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)
带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...
- BZOJ3196:二逼平衡树(线段树套Splay)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
随机推荐
- RadioButton使用
RadioButton和CheckBox差不多,这里只写一个,因为我本身不是学andorid,所以就当给自己留一个备份,省的每次用到都需要代码敲一次,很麻烦 1.如果想选中时想改变颜色可以设置一个xm ...
- pycharm如何设置注释的字体颜色
一.pycharm如何设置注释的字体颜色 1.打开pycharm编辑器,file > settings > Editor > Color Scheme > python > ...
- H5-FileReader实现图片预览&Ajax上传文件
图片预览 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- java取得汉字拼音(pinyin4j)
jar包:pinyin4j.jar 基本用法: String[] pinyin = PinyinHelper.toHanyuPinyinStringArray('重'); 例如“重”字,该方法返回一个 ...
- bootbox.js官方文档中文版
bootbox.js官方文档中文版简介:Bootbox.js是一个小型的JavaScript库,基于Bootstrap模态框开发,用于创建可编程的对话框. 不像原生的alert等对话框,所有的Boot ...
- PHP数组和字符串的处理函数汇总
大部分数组处理函数array_chunk — 将一个数组分割成多个array_column — 返回数组中指定的一列array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的 ...
- [vue]声明式导航和编程式导航
声明式导航和编程式导航 共同点: 都能进行导航,都可以触发路由,实现组件切换 区别: 写法不一样,声明式导航是写在组件的template中,通过router-link来触发,编程式导航写在js函数中, ...
- Python Socket实现文件上传(TCP协议)
在TCP协议下通过socket模块实现文件上传 #!/usr/bin/env python # -*- coding: utf-8 -*- # desc: tcp_server_file_upload ...
- k8s 容器的生命周期钩子
钩子有两个一个容器起之前定义一个动作PostStart,容器关闭之前定义一个动作PreStop 动作可以是一个命令或http请求 示例 spec: containers: - lifecycle: p ...
- [LeetCode] 154. Find Minimum in Rotated Sorted Array II_Hard
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...