P3380 【模板】二逼平衡树(树套树)

前置芝士 P3369 【模板】普通平衡树

线段树套平衡树

这里写的是线段树+splay(不吸氧竟然卡过了)

对线段树的每个节点都维护一颗平衡树

每次把给定区间内

线段树上节点维护的平衡树的信息

查询一遍就好辣

$opt2$:每次二分一个答案k,蓝后用$opt1$跑,再判断偏大还是偏小

我真的要好好背背splay的各种神仙操作了TAT

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
inline int Max(int a,int b){return a>b?a:b;}
inline int Min(int a,int b){return a<b?a:b;}
void read(int &x){
static char c=getchar();x=;
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') x=x*+(c^),c=getchar();
}
#define N 50005
const int inf=;
struct node{
int ch[],siz,v,fa;
void clear(){ch[]=ch[]=v=fa=siz=;}
}a[];
int n,m,u,A[N];
queue <int> lit;
int New(){
if(lit.empty()) return ++u;
int p=lit.front(); lit.pop(); return p;
}
struct Splay{
#define lc a[x].ch[0]
#define rc a[x].ch[1]
int rt,re;
inline void up(int x){a[x].siz=a[lc].siz+a[rc].siz+;}
inline int whi(int y,int x){return a[y].ch[]==x;}
void turn(int x,int &k){
int y=a[x].fa,z=a[y].fa,l=whi(y,x),r=l^;
if(y==k) k=x;
else a[z].ch[whi(z,y)]=x;
a[a[x].ch[r]].fa=y; a[y].fa=x; a[x].fa=z;
a[y].ch[l]=a[x].ch[r]; a[x].ch[r]=y;
up(y); up(x);
}
void splay(int x,int &k){
for(;x!=k;turn(x,k)){
int y=a[x].fa,z=a[y].fa;
if(y!=k) turn((whi(z,y)^whi(y,x))?x:y,k);
}
}
int find(int x,int k){
while(a[lc].siz+!=k){
if(a[lc].siz+>=k) x=lc;
else k=k-a[lc].siz-,x=rc;
}return x;
}
int torank(int k){
int x=rt,re=,id=;
while(x){
if(a[x].v==k) id=x;
if(a[x].v>=k) x=lc;
else re+=a[lc].siz+,x=rc;
}if(id) splay(id,rt);//
return re;
}
void ins(int k){
int x=rt,Fa=;
while(x) Fa=x,x=a[x].ch[a[x].v<=k];
x=New(); a[x].v=k,a[x].fa=Fa;
if(rt) a[Fa].ch[a[Fa].v<=k]=x,splay(x,rt);
else rt=x;
}
void del(int k){
int x=rt,p,tmp;
while(a[x].v!=k) x=a[x].ch[a[x].v<=k];
splay(x,rt); tmp=rt;
if(lc&&rc){//
p=find(rt,a[lc].siz); splay(p,lc),x=rt;
a[lc].ch[]=rc,a[rc].fa=lc;
rt=lc,a[rt].fa=,up(rt);
}else if(lc) a[lc].fa=,rt=lc;
else if(rc) a[rc].fa=,rt=rc;
else rt=;
a[tmp].clear(); lit.push(tmp);
}
void Pre(int x,int k){
if(!x) return;
if(re<a[x].v&&a[x].v<k) re=a[x].v;
Pre(a[x].ch[a[x].v<k],k);
}
void Last(int x,int k){
if(!x) return ;
if(k<a[x].v&&a[x].v<re) re=a[x].v;
Last(a[x].ch[a[x].v<=k],k);
}
int pre(int k){re=-inf;Pre(rt,k);return re;}
int last(int k){re=inf;Last(rt,k);return re;}
#undef lc
#undef rc
}s[N<<];
struct Seg_tree{
#define lc o<<1
#define rc o<<1|1
#define mid (l+r)/2
void Ins(int o,int l,int r,int x,int v){
s[o].ins(v);
if(l==r) return ;
if(x<=mid) Ins(lc,l,mid,x,v);
else Ins(rc,mid+,r,x,v);
}
int Ask1(int o,int l,int r,int x1,int x2,int v){
if(x1<=l&&r<=x2) return s[o].torank(v);
int re=;
if(x1<=mid) re+=Ask1(lc,l,mid,x1,x2,v);
if(x2>mid) re+=Ask1(rc,mid+,r,x1,x2,v);
return re;
}
void Modi(int o,int l,int r,int x,int v1,int v2){
s[o].del(v1); s[o].ins(v2);
if(l==r) return ;
if(x<=mid) Modi(lc,l,mid,x,v1,v2);
else Modi(rc,mid+,r,x,v1,v2);
}
int Ask4(int o,int l,int r,int x1,int x2,int v){
if(x1<=l&&r<=x2) return s[o].pre(v);
int re=-inf;
if(x1<=mid) re=Max(re,Ask4(lc,l,mid,x1,x2,v));
if(x2>mid) re=Max(re,Ask4(rc,mid+,r,x1,x2,v));
return re;
}
int Ask5(int o,int l,int r,int x1,int x2,int v){
if(x1<=l&&r<=x2) return s[o].last(v);
int re=inf;
if(x1<=mid) re=Min(re,Ask5(lc,l,mid,x1,x2,v));
if(x2>mid) re=Min(re,Ask5(rc,mid+,r,x1,x2,v));
return re;
}
#undef lc
#undef rc
#undef mid
}T;
int main(){
read(n);read(m); register int i; int q1,q2,q3,q4;
for(i=;i<=n;++i) read(A[i]),T.Ins(,,n,i,A[i]);
while(m--){
read(q1);read(q2);read(q3);
switch(q1){
case :{read(q4),printf("%d\n",T.Ask1(,,n,q2,q3,q4)+);break;}//排名要+1,算上自己
case :{
read(q4);
int l=,r=1e8;
while(l<r){ //二分比较特殊,每次二分的mid要偏大一点
int mid=(l+r+)/;
if(T.Ask1(,,n,q2,q3,mid)<q4) l=mid;
else r=mid-;
}printf("%d\n",l);
break;
}
case :{T.Modi(,,n,q2,A[q2],q3),A[q2]=q3;break;}
case :{read(q4),printf("%d\n",T.Ask4(,,n,q2,q3,q4));break;}
case :{read(q4),printf("%d\n",T.Ask5(,,n,q2,q3,q4));break;}
}
}return ;
}

P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)的更多相关文章

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

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

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

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

  3. 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)

    P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...

  4. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  5. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  6. BZOJ 3218(a + b Problem-二分图套值域线段树)

    出这题的人是怎么想出来的…… 言归正传,这题是二分图套值域线段树. 首先经过 @Vfleaking的神奇建图后,把图拆成二分图, 不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可 ...

  7. 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)

    线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...

  8. 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  9. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  10. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. 【LeetCode每天一题】Next Permutation(下一个排列)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  2. [LeetCode] 441. Arranging Coins_Easy tag: Math

    You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...

  3. Java Selenium - 元素操作 (二)

    一篇概括了常用的元素定位方法,但是找到元素还是不够的,模拟鼠标的操作,完成各个功能点的自动操作才是关键. 下面是常见的页面元素操作会涉及到的方法,不是很全,比较复杂的后面单独拿出来做案例. 一, 输入 ...

  4. idc指令相关

    #按不同数据类型打印当前地址opcode print Byte(ea) print Word(ea) print Dword(ea)

  5. php 提取多维数组指定列

    前言:有时候在开发中会遇到这样的问题,我们需要把有规律的多维数组按照纵向(列)取出,有下面的方法可用: 我们将拿下面的数组来处理: 1 $arr = array( 2 '0' => array( ...

  6. node.js初识11

    1.EJS  Embedded JavaScript templates 模板引擎 .EJS的效率不高,因为他后台是通过字符串来处理的 <ul> <% for(var i = 0 ; ...

  7. MyBatis基础入门《六》Like模糊查询

    MyBatis基础入门<六>Like模糊查询 描述: 未改动的文件,不再粘贴出来.项目中SQL的xml映射文件重要标签如下: mapper namespace cache 配置给定命令空间 ...

  8. ubuntu 安装/卸载nginx及常用命令

    安装命令 sudo apt-get update #更新apt sudo apt-get install nginx #安装nginx 启动/重启/停止命令 一. /etc/init.d/nginx ...

  9. 从PHP官方镜像创建开发镜像

    https://xlange.com/post/dockerfile-baseon-official-php-image.html

  10. Mongodb内嵌数组的完全匹配查询

    样例数据: {      "cNo" : "11",     "Details" : [         {              &q ...