题目链接

平衡树系列最后一题

坑啊

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 二逼平衡树的更多相关文章

  1. BZOJ3196二逼平衡树——线段树套平衡树(treap)

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

  2. bzoj3196 二逼平衡树 树状数组套线段树

    题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...

  3. bzoj3196 二逼平衡树 树套树(线段树套Treap)

    Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4697  Solved: 1798[Submit][Status][D ...

  4. BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)

    我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...

  5. [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]

    题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...

  6. BZOJ3196 二逼平衡树 【线段树套平衡树】

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

  7. BZOJ3196——二逼平衡树

    1.题目大意:给你一个序列,有5种操作,都有什么呢... 1> 区间第k小 这个直接用二分+树套树做 2> 区间小于k的有多少 这个直接用树套树做 3> 单点修改 这个直接用树套树做 ...

  8. luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)

    带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...

  9. BZOJ3196:二逼平衡树(线段树套Splay)

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

随机推荐

  1. MathWorks.MATLAB.NET.Arrays.MWArray”的类型初始值设定项引发异常 解决方法

    原因 用的是matlab7运行时,后面又安装了matlab11,后面又重新安装了matlab7运行时,c盘下就有二个运行时的版本了,程序引用了后面的那个,编译后就出上面的问题 解决方法 1重新引用上面 ...

  2. 【剑指offer】两个链表的第一个公共结点

    一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n  List2 长度:b+n, 且 a&l ...

  3. 反射入门-浅谈反射用途_根据Ado游标对象创建list集合

    本人大二菜鸟一只,今天在上课期间有个同学看着C#反射的内容说反射没什么用,一时之间也想不到什么更好的例子,就写了个根据泛型类型和游标反射创建List集合的Demo. 首先创建一个用于封装对应数据的en ...

  4. poi 生成图片到excel

    try { InputStream iss = new FileInputStream("D:\\test.xlsx"); XSSFWorkbook wb = new XSSFWo ...

  5. vue中使用lodash

    1.安装:npm i --save lodash 2.引入:import _from 'lodash' 3.使用: <template> <div class="templ ...

  6. vue中根据生日计算年龄

    getage() { var birthdays = new Date(this.birthday.replace(/-/g, "/")); var d = new Date(); ...

  7. [vue]data数据属性及ref获取dom

    data项的定义 this.$refs获取dom 获取不到数据 这样中转下才ok 小结: data里不能用this.$ref. 另外使用visjs时候 view-source:http://visjs ...

  8. Linux下安装zookeeper集群(奇数个)

    1.  解压zookeeper压缩包 2.  data里创建“myid”文件(命令touch myid),内容是1(命令 echo 1 >> myid) 3.  zoo.cnf里配置dat ...

  9. print()与println()区别

    print 不会换行,println会换行 例如:print(a):print(b):结果为: abprintln(a):println(b):结果为: a b

  10. Linux基础(一)流程控制

    Shell 流程控制 if 语句语法格式1: 写成一行(适用于终端命令提示符):if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo ...