BZOJ

LOJ

洛谷


这题不难啊,我怎么就那么傻,拿随便一个节点去模拟。。

我们只需要能够维护,将最小值或最大值转到根。模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\(+1\),且除右儿子外所有点的父子关系不会改变。最大值同理。

因为右子树和右子树外的所有点的值域是连续的,所以按值域为下标维护线段树,区间加即可。

至于怎么维护右子树的范围?不就是\((val_x,val_{fa[x]})\)吗。。

如果是删除,把它转到根后,对所有点深度\(-1\)即可。

考虑如何插入。插入的位置肯定是它的前驱后继之间啊。所以用set或此时的线段树找到前驱后继,在对应位置插入就行了(线段树似乎有些麻烦)。然后在线段树上更新一下\(dep\)。


//7276kb	824ms
#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5; int n,root,val[N],ref[N],fa[N],son[N][2],opt[N];
std::set<int> st;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S N<<2
int val[S];
#undef S
#define Upd(rt,v) val[rt]+=v
// #define Update(rt) exist[rt]=exist[ls]||exist[rs]
inline void PushDown(int rt)
{
Upd(ls,val[rt]), Upd(rs,val[rt]), val[rt]=0;
}
void Modify(int l,int r,int rt,int L,int R,int v)
{
if(L<=l && r<=R) {Upd(rt,v); return;}
if(val[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R,v);
if(m<R) Modify(rson,L,R,v);
}
void Set(int l,int r,int rt,int p,int v)
{
while(l!=r)
{
if(val[rt]) PushDown(rt);
int m=l+r>>1;
p<=m ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
val[rt]=v;
}
int Query(int l,int r,int rt,int p)
{
while(l!=r)
{
if(val[rt]) PushDown(rt);
int m=l+r>>1;
p<=m ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
return val[rt];
}
pr Query2(int l,int r,int rt,int p)
{
while(l!=r)
{
if(val[rt]) PushDown(rt);
int m=l+r>>1;
p<=m ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
return mp(rt,val[rt]);
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline int Find(int x)
{
int l=1,r=n,mid;
while(l<r)
if(ref[mid=l+r>>1]<x) l=mid+1;
else r=mid;
return l;
}
#define S 1,n,1
int Insert(int x)
{
if(st.empty()) {st.insert(root=x), T.Set(S,x,1); return 1;}
std::set<int>::iterator it=st.upper_bound(x);
int p,v;
if(it!=st.end()&&!son[*it][0]) son[p=*it][0]=x;
else son[p=*(--it)][1]=x;
st.insert(x), fa[x]=p, T.Set(S,x,v=T.Query(S,p)+1);
return v;
}
int RotateMin()
{
int x=*st.begin();
if(!fa[x]) return 1;
pr v=T.Query2(S,x);
T.Modify(S,fa[x],n,1), T.val[v.first]=1;//T.Set(S,x,1);
son[fa[x]][0]=son[x][1], fa[son[x][1]]=fa[x], fa[x]=0;
son[x][1]=root, fa[root]=x, root=x;
return v.second;
}
int RotateMax()
{
int x=*st.rbegin();
if(!fa[x]) return 1;
pr v=T.Query2(S,x);
T.Modify(S,1,fa[x],1), T.val[v.first]=1;//T.Set(S,x,1);
son[fa[x]][1]=son[x][0], fa[son[x][0]]=fa[x], fa[x]=0;
son[x][0]=root, fa[root]=x, root=x;
return v.second;
}
int DeleteMin()
{
int v=RotateMin(),x=*st.begin();
st.erase(x), T.Modify(S,1,n,-1), fa[root=son[x][1]]=0, son[x][1]=0;
return v;
}
int DeleteMax()
{
int v=RotateMax(),x=*st.rbegin();
st.erase(x), T.Modify(S,1,n,-1), fa[root=son[x][0]]=0, son[x][0]=0;
return v;
} int main()
{
// freopen("splay.in","r",stdin);
// freopen("splay.out","w",stdout); const int Q=read(); int n=0;
for(int i=1; i<=Q; ++i)
if((opt[i]=read())==1) ++n, val[n]=ref[n]=read();
std::sort(ref+1,ref+1+n), ::n=n;
for(int i=1,t=0; i<=Q; ++i)
switch(opt[i])
{
case 1: printf("%d\n",Insert(Find(val[++t]))); break;
case 2: printf("%d\n",RotateMin()); break;
case 3: printf("%d\n",RotateMax()); break;
case 4: printf("%d\n",DeleteMin()); break;
case 5: printf("%d\n",DeleteMax()); break;
}
return 0;
}

BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)的更多相关文章

  1. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  2. 【BZOJ4825】[Hnoi2017]单旋 线段树+set

    [BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...

  3. 【bzoj4825】[Hnoi2017]单旋 线段树+STL-set

    题目描述 H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能.有一天 ...

  4. 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)

    题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...

  5. bzoj 4825: [Hnoi2017]单旋 [lct]

    4825: [Hnoi2017]单旋 题意:有趣的spaly hnoi2017刚出来我就去做,当时这题作死用了ett,调了5节课没做出来然后发现好像直接用lct就行了然后弃掉了... md用lct不知 ...

  6. 4825: [Hnoi2017]单旋

    4825: [Hnoi2017]单旋 链接 分析: 以后采取更保险的方式写代码!!!81行本来以为不特判也可以,然后就总是比答案大1,甚至出现负数,调啊调啊调啊调~~~ 只会旋转最大值和最小值,以最小 ...

  7. 【LG3721】[HNOI2017]单旋

    [LG3721][HNOI2017]单旋 题面 洛谷 题解 20pts 直接模拟\(spaly\)的过程即可. 100pts 可以发现单旋最大.最小值到根,手玩是有显然规律的,发现只需要几次\(lin ...

  8. BZOJ:4825: [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  9. 【刷题】BZOJ 4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

随机推荐

  1. python基础复习

    复习-基础 一.review-base 其他语言吗和python的对比 c vs Python c语言是python的底层实现,解释器就是由python编写的. c语言开发的程序执行效率高,开发现率低 ...

  2. Red Language

    官网地址:http://www.red-lang.org/ 源代码地址:https://github.com/red/red   通过github上的Readme,可以完成Hello World的学习 ...

  3. Supervisor Linux程序进程管理

    Supervisor 介绍 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.由于在linux中 ...

  4. EF批量插入数据(Z.EntityFramework.Extensions)

    EF用原生的插入数据方法DbSet.ADD()和 DbSet.AddRange()都很慢.所以要做大型的批量插入只能另选它法. 1.Nugget 2.代码 using EF6._0Test.EF; u ...

  5. 键盘Hook【Delphi版】

    原文:https://www.cnblogs.com/edisonfeng/archive/2012/05/18/2507858.html 一.钩子的基本概念 a) Hook作用:监视windows消 ...

  6. vector的 []

    摘自<C++编程剖析> #include <iostream> #include <vector> using namespace std; int main() ...

  7. 令人疑惑的 std::remove 算法

    摘自<Effective STL>第32条 remove的声明: template<class ForwardIterator, class T> ForwardIterato ...

  8. [转]EndNote导入IEEE文献的方法

    EndNote导入IEEE文献的方法.IEEE虽然可以批量导出,但是批量导出的是CSV格式.如果想导入到EndNote,需要一个个文献的导入.本文介绍一下IEEE导出文献并导入到EndNote的方法. ...

  9. sqlserver中的数据转换与子查询

    数据类型转换 --cast转换 select CAST(1.23 as int) select CAST(1.2345 as decimal(18,2)) select CAST(123 as var ...

  10. C#操作xml SelectNodes,SelectSingleNode总是返回NULL

    SelectNodes,SelectSingleNode总是返回NULL 原文地址:http://www.cnblogs.com/linlf03/archive/2011/11/30/2268705. ...