单旋
  • 这道题做法贼多,LCT,splay,线段树什么的貌似都行。
  • 像我这种渣渣只会线段树了(高级数据结构学了也不会用)。
  • 首先离线所有操作,因为不会有两个点值重复,所以直接离散。
  • 一颗线段树来维护所有点的深度,并将所有值丢进\(set\)中。
  • 插入操作,在set找到前驱后继,前驱没有右儿子就放前驱右儿子,否则放后继左儿子,同时用\(ch\)和\(fa\)假装模拟树的形态。
  • 旋转操作,在\(set\)里找到节点,可以发现旋转操作该点儿子深度不变,其他点深度加一,处理一下父子关系,然后线段树修改区间即可。
  • 删除操作,先旋转操作,\(root\)一定只有一个儿子,直接删掉\(root\)即可,将所有点深度减一
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=1e5+5;
bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
template<typename T>inline T read()
{
T f=1,ans=0;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
template<typename T>inline void write(T x,char y)
{
if(x==0)
{
putchar('0');putchar(y);
return;
}
if(x<0)
{
putchar('-');
x=-x;
}
static char wr[20];
int top=0;
for(;x;x/=10)wr[++top]=x%10+'0';
while(top)putchar(wr[top--]);
putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("3721.in","r",stdin);
freopen("3721.out","w",stdout);
#endif
}
int n,opt[N][2];
int a[N],top;
void input()
{
n=read<int>();
For(i,1,n)
{
opt[i][0]=read<int>();
if(opt[i][0]==1)a[++top]=read<int>(),opt[i][1]=a[top];
}
}
namespace Tree
{
#define mid ((l+r)>>1)
#define lson h<<1,l,mid
#define rson h<<1|1,mid+1,r
ll lazy[N<<2],sum[N<<2];
void push_down(int h,int l,int r)
{
if(!lazy[h])return;
int ls=h<<1,rs=ls|1;
lazy[ls]+=lazy[h];lazy[rs]+=lazy[h];
sum[ls]+=lazy[h]*1ll*(mid-l+1);
sum[rs]+=lazy[h]*1ll*(r-mid);
lazy[h]=0;
}
void push_up(int h)
{
sum[h]=sum[h<<1]+sum[h<<1|1];
}
void update(int h,int l,int r,int s,int t,int v)
{
if(s<=l&&r<=t)
{
lazy[h]+=v;
sum[h]+=1ll*v*1ll*(r-l+1);
}
else
{
push_down(h,l,r);
if(s<=mid)update(lson,s,t,v);
if(mid<t)update(rson,s,t,v);
push_up(h);
}
}
int query(int h,int l,int r,int pos)
{
if(l==r)return sum[h];
push_down(h,l,r);
int res;
if(pos<=mid)res=query(lson,pos);
else res=query(rson,pos);
push_up(h);
return res;
}
void modify(int h,int l,int r,int pos,int v)
{
if(l==r)sum[h]=v;
else
{
push_down(h,l,r);
if(pos<=mid)modify(lson,pos,v);
else modify(rson,pos,v);
push_up(h);
}
}
}
set<int>s;
set<int>::iterator it;
int root,ch[N][2],fa[N];
typedef pair<int,int>pii;
#define fir first
#define sec second
void insert(int x)
{
int pre,predep;
it=s.insert(x).fir;
if(!root)
{
root=x;
Tree::modify(1,1,n,x,1);
puts("1");
return;
}
if(it==s.begin())
{
++it;pre=*it;
fa[x]=pre;ch[pre][0]=x;
}
else
{
--it;
if(!ch[*it][1])
{
pre=*it;
fa[x]=pre;
ch[pre][1]=x;
}
else
{
++it;++it;
pre=*it;
fa[x]=pre;
ch[pre][0]=x;
}
}
predep=Tree::query(1,1,n,pre);
write(predep+1,'\n');
Tree::modify(1,1,n,x,predep+1);
}
void clear(int x)
{
ch[x][0]=ch[x][1]=fa[x]=0;
}
void rotate_min()
{
it=s.begin();
int x=*it;
if(x==root){puts("1");return;}
int y=ch[x][1],oldroot=root,pre=fa[x];
write(Tree::query(1,1,n,x),'\n');
if(y)Tree::update(1,1,n,x+1,fa[x]-1,-1);
Tree::update(1,1,n,1,n,1);
Tree::modify(1,1,n,x,1);
root=x;
ch[x][1]=oldroot;fa[oldroot]=x;
ch[pre][0]=y;fa[y]=pre;
}
void del_min()
{
rotate_min();
s.erase(root);
Tree::update(1,1,n,1,n,-1);
if(!ch[root][0]&&!ch[root][1])clear(root),root=0;
else
{
int oldroot=root;
root=ch[root][1];
clear(oldroot);fa[root]=0;
}
}
void rotate_max()
{
it=s.end();--it;
int x=*it;
if(x==root){puts("1");return;}
write(Tree::query(1,1,n,x),'\n');
int y=ch[x][0],oldroot=root,pre=fa[x];
if(y)Tree::update(1,1,n,fa[x]+1,x-1,-1);
Tree::update(1,1,n,1,n,1);
Tree::modify(1,1,n,x,1);
root=x;
fa[oldroot]=x;ch[x][0]=oldroot;
ch[pre][1]=y;fa[y]=pre;
}
void del_max()
{
rotate_max();
s.erase(root);
Tree::update(1,1,n,1,n,-1);
if(!ch[root][0]&&!ch[root][1])clear(root),root=0;
else
{
int oldroot=root;
root=ch[root][0];
clear(oldroot);fa[root]=0;
}
}
void work()
{
sort(a+1,a+top+1);
For(i,1,n)
{
if(opt[i][0]==1)
{
opt[i][1]=lower_bound(a+1,a+top+1,opt[i][1])-a;
insert(opt[i][1]);
}
else if(opt[i][0]==2)rotate_min();
else if(opt[i][0]==3)rotate_max();
else if(opt[i][0]==4)del_min();
else if(opt[i][0]==5)del_max();
}
}
int main()
{
file();
input();
work();
return 0;
}

HNOI2017单旋的更多相关文章

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

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

  2. 【LG3721】[HNOI2017]单旋

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

  3. 4825: [Hnoi2017]单旋

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

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

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

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

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

  6. bzoj4825 [Hnoi2017]单旋

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

  7. BZOJ:4825: [Hnoi2017]单旋

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

  8. HNOI2017 单旋

    题目描述 网址:https://www.luogu.org/problemnew/show/3721 大意: 有一颗单旋Splay(Spaly),以key值为优先度,总共有5个操作. [1] 插入一个 ...

  9. P3721 [AH2017/HNOI2017]单旋

    题目:https://www.luogu.org/problemnew/show/P3721 手玩一下即可AC此题. 结论:插入x后,x要么会成为x的前驱的右儿子,要么成为x的后继的左儿子,这取决于它 ...

随机推荐

  1. BZOJ4985 评分 二分答案、DP

    传送门 题意:自己去看 答案满足单调性,所以考虑二分答案. 二分答案很好想,但是check并不是很好想. 考虑DP:设$f_i$表示队列中第$i$个人的分数$\geq \, mid$的代价,最开始$N ...

  2. 【APIO2016】烟火表演

    题面 题解 神仙题目啊QwQ 设\(f_i(x)\)表示以第\(i\)个点为根的子树需要\(x\)秒引爆的代价. 我们发现,这个函数是一个下凸的一次分段函数. 考虑这个函数合并到父亲节点时会发生怎样的 ...

  3. Bayesian Personalized Ranking 算法解析及Python实现

    1. Learning to Rank 1.1 什么是排序算法 为什么google搜索 ”idiot“ 后,会出现特朗普的照片? “我们已经爬取和存储了数十亿的网页拷贝在我们相应的索引位置.因此,你输 ...

  4. HBase最佳实践-管好你的操作系统

    本文由  网易云发布. 作者:范欣欣 本篇文章仅限本站分享,如需转载,请联系网易获取授权. 操作系统这个话题其实很早就想拿出来和大家分享,拖到现在一方面是因为对其中各种理论理解并不十分透彻,怕讲不好: ...

  5. 腾讯云COS体验

    其实这篇文章本来是推荐COS的,写了一半发现COS的免费额度取消了,2019年之后的开通的用户免费6个月,老用户不受影响,这还让我怎么推荐啊?!写都写了,删掉岂不是白浪费时间? 都怪你!腾讯云! 起因 ...

  6. 图像数据增强 (Data Augmentation in Computer Vision)

    1.1 简介 深层神经网络一般都需要大量的训练数据才能获得比较理想的结果.在数据量有限的情况下,可以通过数据增强(Data Augmentation)来增加训练样本的多样性, 提高模型鲁棒性,避免过拟 ...

  7. SpringMvc执行过程

    --Test过程: 1. 先执行各种 Filter 2. HttpServlet.service(ServletRequest req, ServletResponse res) 3. HttpSer ...

  8. kvm虚拟化管理平台WebVirtMgr部署-完整记录(1)

    公司机房有一台2U的服务器(64G内存,32核),由于近期新增业务比较多,测试机也要新增,服务器资源十分有限.所以打算在这台2U服务器上部署kvm虚拟化,虚出多台VM出来,以应对新的测试需求.当KVM ...

  9. C. Vasya and Multisets

    传送门 [http://codeforces.com/contest/1051/problem/C] 题意 给你一堆数,问是否可以分为两堆使得两堆里只出现一下的数字的种类相等,可以输出任意一种分的方式 ...

  10. 《吃了么》Alpha版本发布说明

    1.功能描述  功能一  查询周边餐厅 选中一条后,会跳转到相应餐厅的网址,获取具体的信息: 功能二 查询指定地点地餐厅 功能三 查询菜谱 具体的菜谱: 还有收藏夹的功能,点击标题栏的心形图标可以将菜 ...