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 ...
随机推荐
- linux curl命令如何上传本地文件夹和下载文件
本地有一个文件夹为my_dir,里面有四个文件,分别是test1.txt,user_account,tools_user,plans 要把这个my_dir文件夹传到ftp 192.168.8.251 ...
- [LeetCode] 876. Middle of the Linked List_Easy tag: Linked List ** slow, fast pointers
Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...
- 配置完centos 6以后,大概需要安装的软件(主要是yum)
根据实践,把我的经验说一下,以后我自己也可以按照这个快速安装软件. 1. 配置源.百度网盘的tools/download/linux已经放了几个挺重要的 东西了. yum -y install epe ...
- (已解决) eclipse提示报错"serializing cdt project settings"解决方案
最近在使用eclipse作为cocos2dx的交叉编译工具.但是某天突然相关工程打不开,打开eclipse直接提示 “serializing cdt project settings” has enc ...
- cookie和session必须了解的东西
Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...
- EF或LINQ 查询时使用IN并且根据列表自定义排序方法
EF和LINQ改变了原有的手写SQL时期的一些编码方法,并且增强了各数据库之间的移植性简化了开发时的代码量和难度,由于很多人不熟,经常会碰到一些写SQL语句时经常会用到的一些方法,而使用EF或LINQ ...
- Usefull Resources
Sql Server Profiler 1. http://www.cnblogs.com/Fooo/archive/2013/02/19/2916789.html 2. http://5439255 ...
- WinSock学习笔记
Socket(套接字)◆先看定义: typedef unsigned int u_int; typedef u_int SOCKET; ◆Socket相当于进行网络通信两端的插座,只要对方的Socke ...
- 交替最小二乘ALS
https://www.cnblogs.com/hxsyl/p/5032691.html http://www.cnblogs.com/skyEva/p/5570098.html 1. 基础回顾 矩阵 ...
- Spark学习之路 (十二)SparkCore的调优之资源调优
摘抄自:https://tech.meituan.com/spark-tuning-basic.html 一.概述 在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都 ...