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 【模板】二逼平衡树(树套树)(线段树套平衡树)的更多相关文章
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- BZOJ 3218(a + b Problem-二分图套值域线段树)
出这题的人是怎么想出来的…… 言归正传,这题是二分图套值域线段树. 首先经过 @Vfleaking的神奇建图后,把图拆成二分图, 不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可 ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)
模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
随机推荐
- spring + mybatis配置及网络异常设置
Spring引入mybatis <beans xmlns="http://www.springframework.org/schema/beans" xmlns:contex ...
- zabbix 自定义监控文本内容
需求:监控服务器硬盘使用率是否有超过80%的 需要监控的文本 root@zabbix zabbix]# cat /etc/zabbix/scripts/data/monitor_disk.txt &q ...
- git revert 撤销merge的动作
在执行完git merge提交以后,通常会merge过的分支的提交记录都带过来,比如A分支merge到了B分支,那么B分支上肯定有A分支的提交记录,如果此时要回退这个merge动作,是产生一条reve ...
- node代码打包为 exe文件---端口进程关闭demo
最近用到 java,用tomcat起的服务,经常服务关了,对应的进程还在跑,导致再次启动服务失败,需要手动关闭进程. 使用 dos命令虽然只有两行,总是输,也很烦. netstat -ano | fi ...
- WinRAR 5.40 & 4.20 & 3.93 的注册码 - rarreg.key
把下面的数据复制到“记事本”中,用文件名“rarreg.key”命名该文件,保存到WinRAR安装文件夹即完成注册. 以下4个Key随便选一个复制都可以. WinRAR 5.40 版Key,复制箭头中 ...
- iOS 崩溃分析
崩溃统计分析,在APP中是非常常见一种优化APP,发现APP的BUG的方式. 1.异常处理 可通过try catch 方式处理,如果发生异常,会走catch ,最终走fianlly.对一些我们不想他崩 ...
- 点击地面时,若鼠标点击的偶数次使得Cube向点击点移动,并且点击奇数次Cube变色
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ray10 : ...
- kali linux主题下载
主题下载网站 https://www.gnome-look.org/ 下载好安装包后解压 将文件夹移动到 usr/share/theme/ 下 mv download ../usr/share/the ...
- ASP.Net 获取Form表单值
新建一HtmlPage1.html,如下post发送() <body> <form enctype="multipart/form-data" action=&q ...
- python windows安装 SQLServer pymssql,
1.到正儿八经的网站下载文件,找到适合自己的版本 2.把文件放到一个地方,能让pip找到就行, 不放scripts下面的话, 恐怕会报错“FileNotFoundError" 3. 走到pi ...