题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3196

人生中第一棵树套树!

写了一个晚上,成功卡时 9000ms+ 过了!

很要注意数组的大小,因为是树*树的大小嘛!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=2e6+,nn=5e4+,inf=1e9;//2e6!!
int n,m,tot,siz[maxn],c[maxn][],fa[maxn],key[maxn],mn,mx,a[nn];
struct N{
int l,r,rt;
}t[nn<<];
void update(int x){siz[x]=siz[c[x][]]+siz[c[x][]]+;}
void rotate(int x)
{
int y=fa[x],z=fa[y],d=(c[y][]==x);
if(z!=)c[z][c[z][]==y]=x;
fa[x]=z; fa[y]=x; fa[c[x][d^]]=y;
c[y][d]=c[x][d^]; c[x][d^]=y;
update(y); update(x);
}
void splay(int x,int f)//fa[x]=f
{
while(fa[x]!=f)
{
int y=fa[x],z=fa[y];
if(z!=f)// z 而非 y
{
if((c[y][]==x)^(c[z][]==y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
int find_pre(int x,int v)
{
if(!x)return ;
if(key[x]>=v) return find_pre(c[x][],v);
else
{
int y=find_pre(c[x][],v);
if(y)return y; else return x;
}
}
int find_k(int x,int k)
{
// if(!x)return 0;
if(siz[c[x][]]==k-)return x;
if(siz[c[x][]]>k-)return find_k(c[x][],k);
return find_k(c[x][],k-siz[c[x][]]-);
}
int find_suc(int x,int k)//后继
{
if(!x)return ;
if(key[x]<=k)return find_suc(c[x][],k);
else
{
int y=find_suc(c[x][],k);
if(y)return y; else return x;//说不定就是 x
}
}
int find_Suc(int x,int k)//相等中最小的
{
if(!x)return ;
if(key[x]<k)return find_Suc(c[x][],k);
else
{
int y=find_Suc(c[x][],k);
if(y)return y; else return x;//说不定就是 x
}
}
int query_k(int &x,int k)//查询 k 的排名
{
int p=find_Suc(x,k); splay(p,);//相等中最小的
x=p;
return siz[c[p][]]-;// -inf
}
int query(int &x,int k)//二分用
{
int p=find_suc(x,k); splay(p,);
x=p;
return siz[c[p][]]-;// -inf
}
void insert(int &x,int v)
{
int p=find_pre(x,v); splay(p,);
int y=find_k(c[p][],); splay(y,p);//p
tot++; siz[tot]=; fa[tot]=y; key[tot]=v; c[y][]=tot;
update(y); update(p);
x=p;//rt
}
void del(int &x,int v)
{
int p=find_pre(x,v); splay(p,);
int y=find_k(c[p][],); splay(y,p);//p
fa[c[y][]]=; c[y][]=;
update(y); update(p);
x=p;
}
void build(int x,int l,int r)
{
t[x].l=l; t[x].r=r;
t[x].rt=++tot; siz[tot]=; fa[tot]=; c[tot][]=tot+; key[tot]=-inf;
tot++; siz[tot]=; fa[tot]=tot-; key[tot]=inf;
for(int i=l;i<=r;i++)insert(t[x].rt,a[i]);
if(l==r)return;
int mid=(l+r)>>;
build(x<<,l,mid); build(x<<|,mid+,r);
}
int query_k(int x,int l,int r,int k)//查询 k 的排名
{
if(t[x].l>=l && t[x].r<=r)return query_k(t[x].rt,k);//<=k 的个数
int mid=(t[x].l+t[x].r)>>,ret=;//不是 l,r
if(mid>=l)ret+=query_k(x<<,l,r,k);//l,r,无需 l,mid ,因为自带 t[x].l,t[x].r
if(mid<r)ret+=query_k(x<<|,l,r,k);
return ret;
}
int query(int x,int l,int r,int k)//二分用 //<=mid的个数
{
if(t[x].l>=l && t[x].r<=r)return query(t[x].rt,k);
int mid=(t[x].l+t[x].r)>>,ret=;//不是 l,r
if(mid>=l)ret+=query(x<<,l,r,k);
if(mid<r)ret+=query(x<<|,l,r,k);
return ret;
}
void modify(int x,int p,int k)
{
insert(t[x].rt,k); del(t[x].rt,a[p]);
if(t[x].l==t[x].r)return;//
int mid=(t[x].l+t[x].r)>>;
if(p<=mid)modify(x<<,p,k);
else modify(x<<|,p,k);
}
int query_pre(int x,int l,int r,int k)
{
if(t[x].l>=l && t[x].r<=r)return key[find_pre(t[x].rt,k)];//返回 key ,因为需要比较
int mid=(t[x].l+t[x].r)>>,ret=;
if(mid>=l)ret=max(ret,query_pre(x<<,l,r,k));
if(mid<r)ret=max(ret,query_pre(x<<|,l,r,k));
return ret;
}
int query_suc(int x,int l,int r,int k)
{
if(t[x].l>=l && t[x].r<=r)return key[find_suc(t[x].rt,k)];//返回 key ,因为需要比较
int mid=(t[x].l+t[x].r)>>,ret=inf;
if(mid>=l)ret=min(ret,query_suc(x<<,l,r,k));
if(mid<r)ret=min(ret,query_suc(x<<|,l,r,k));
return ret;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
mn=min(mn,a[i]); mx=max(mx,a[i]);
}
build(,,n);
for(int i=,op,l,r,k;i<=m;i++)
{
scanf("%d",&op);
if(op!=)scanf("%d%d%d",&l,&r,&k);
if(op==)printf("%d\n",query_k(,l,r,k)+);//+1
if(op==)
{
int L=mn,R=mx,ans=;
while(L<=R)
{
int mid=(L+R)>>;
if(query(,l,r,mid)>=k)ans=mid,R=mid-;// >也可,因为查询的是 <=mid 的个数
else L=mid+;
}
printf("%d\n",ans);
}
if(op==)
{
int pos; scanf("%d%d",&pos,&k);
modify(,pos,k);
a[pos]=k;//!!!
}
if(op==)printf("%d\n",query_pre(,l,r,k));
if(op==)printf("%d\n",query_suc(,l,r,k));
}
return ;
}

bzoj3196 二逼平衡树——线段树套平衡树的更多相关文章

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

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

  2. [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树

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

  3. bzoj 3196二逼平衡树 线段树套平衡树

    比较裸的树套树,对于区间K值bz上有一道裸题,详见题解http://www.cnblogs.com/BLADEVIL/p/3455336.html(其实题解也不是很详细) //By BLADEVIL ...

  4. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

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

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

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

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

  7. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  8. P3380 【模板】二逼平衡树(树套树) 线段树套平衡树

    \(\color{#0066ff}{ 题目描述 }\) 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上 ...

  9. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

随机推荐

  1. 树莓派 - wiringPi

    wiringPi其实和BCM2835 library类似,也是通过memmap, IOmap来实现在用户空间直接操作底层寄存器 wiringPi http://wiringpi.com/ Wiring ...

  2. LINUX:Contos7.0 / 7.2 LAMP+R 下载安装Php篇

    文章来源:http://www.cnblogs.com/hello-tl/p/7569071.html 更新时间:2017-09-21 16:03 简介 LAMP+R指Linux+Apache+Mys ...

  3. IDE简介

    IDE(Integrated Development Environment) 集成开发环境 十种集成开发工具: 微软 Visual Studio (VS) NetNeans PyCharm Inte ...

  4. Python基础知识点总结

    Python基础知识与常用数据类型 一.Python概述: 1.1.Python的特点: 1.Python是一门面向对象的语言,在Python中一切皆对象 2.Python是一门解释性语言 3.Pyt ...

  5. Poj 2187 旋转卡壳

    Poj 2187 旋转卡壳求解 传送门 旋转卡壳,是利用凸包性质来求解凸包最长点对的线性算法,我们逐渐改变每一次方向,然后枚举出这个方向上的踵点对(最远点对),类似于用游标卡尺卡着凸包旋转一周,答案就 ...

  6. Mac os安装MySQL数据库,系统提示mysql: command not found该怎么办

    当我们安装好MySQL后,在终端输入mysql命令,发现并不能看到自己安装的数据库,这是因为你没有配置环境变量. 在os系统中安装MySQL数据库默认保存在/usr/local/mysql 那么我们应 ...

  7. jquery对JSON字符串的解析--eval函数

    jquery eval解析JSON中的注意点介绍----https://www.jb51.net/article/40842.htm

  8. Linux下汇编语言学习笔记16 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  9. 我的arcgis培训照片7

    来自:http://www.cioiot.com/successview-553-1.html

  10. Django学习系列之captcha 验证码插件

    安装部署 安装captcha pip3. install django-simple-captcha== settings.py中引入captcha INSTALLED_APPS = [ 'djang ...