【BZOJ3678】wangxz与OJ

Description

某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge)。由于他是一位哲♂学的神犇,所以他不打算做题。他发现这些题

目呈线性排列,被标记为1~n号,每道题都有一个难度值(可以<=0)。他决定与这些题目玩♂耍。

1、他可以在某个位置插♂入一些难度值特定的题目。

2、他可以吃♂掉(删除)一段题目。

3、他可以查询某个位置的题目的难度值。

维护一个初始有n个元素的序列(标记为1~n号元素),支持以下操作:

0 p a b (0<=p<=当前序列元素个数) (a<=b) 在p位置和p+1位置之间插入整数:a,a+1,a+2,...,b-1,b。若p为0,插在序列最前面;

1 a b (1<=a<=b<=当前序列元素个数) 删除a,a+1,a+2,...,b-1,b位置的元素;

2 p (1<=p<=当前序列元素个数) 查询p位置的元素。

Input

输入第一行包括两个正整数n(1<=n<=20000),m(1<=m<=20000),代表初始序列元素个数和操作个数。

接下来n个整数,为初始序列元素。

接下来m行,每行第一个为整数sym,

若sym=0,接下来有一个非负整数p,两个整数a,b;

若sym=1,接下来有两个正整数a,b;

若sym=2,接下来有一个正整数p;

p、x、y的含义及范围见题目描述。

在任何情况下,保证序列中的元素总数不超过100000。

保证题目涉及的所有数在int内。

Output

对每个sym=2,输出一行,包括一个整数,代表询问位置的元素。

Sample Input

5 3
1 2 3 4 5
0 2 1 4
1 3 8
2 2

Sample Output

2

题解:容易想到用Splay,我们的Splay的每个节点处维护的不是一个点,而是连续的一段数[a,b]。我们需要实现一个split操作:如果我们想将c和c+1分开,那么我们先找到c所在的节点,将它的后继提上来,并在二者之间新建一个点,将当前节点变成[a,c],并将新点变成[c+1,b]即可。特别地,如果c==b,则不用操作。

其余的操作就很容易了。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
struct node
{
int ch[2],a,b,fa,siz;
}s[200010];
int n,m,tot,rt;
inline void pushup(int x)
{
s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+s[x].b-s[x].a+1;
}
int build(int l,int r)
{
if(l>r) return 0;
int x=(l+r)>>1;
s[x].ch[0]=build(l,x-1),s[x].ch[1]=build(x+1,r);
if(s[x].ch[0]) s[s[x].ch[0]].fa=x;
if(s[x].ch[1]) s[s[x].ch[1]].fa=x;
pushup(x);
return x;
}
inline void rotate(int x,int &k)
{
int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
if(z) s[z].ch[y==s[z].ch[1]]=x;
else if(y==k) k=x;
s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];
if(s[x].ch[d^1]) s[s[x].ch[d^1]].fa=y;
s[x].ch[d^1]=y;
pushup(y),pushup(x);
}
inline void splay(int x,int &k)
{
while(x!=k)
{
int y=s[x].fa,z=s[y].fa;
if(y!=k)
{
if((x==s[y].ch[0])^(y==s[z].ch[0])) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
int find(int x,int y)
{
if(!x) return 0;
if(y>s[s[x].ch[0]].siz&&y<=s[s[x].ch[0]].siz+s[x].b-s[x].a+1) return x;
if(s[s[x].ch[0]].siz>=y) return find(s[x].ch[0],y);
return find(s[x].ch[1],y-s[s[x].ch[0]].siz-s[x].b+s[x].a-1);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void split(int y)
{
int x=find(rt,y+1);
splay(x,rt),splay(find(rt,s[s[x].ch[0]].siz+s[x].b-s[x].a+2),s[x].ch[1]);
if(s[s[x].ch[0]].siz+s[x].b-s[x].a==y) return ;
int z=++tot;
s[z].b=s[x].b,s[x].b=s[x].a+y-s[s[x].ch[0]].siz,s[z].a=s[x].b+1;
s[z].fa=s[x].ch[1],s[s[x].ch[1]].ch[0]=z;
pushup(z),pushup(s[x].ch[1]),pushup(x);
rotate(z,s[x].ch[1]);
}
int main()
{
n=rd(),m=rd();
int i,x,y,a,b,op;
for(i=1;i<=n;i++) s[i+1].a=s[i+1].b=rd();
rt=build(1,n+2),tot=n+2;
for(i=1;i<=m;i++)
{
op=rd();
if(op==0)
{
a=rd(),split(a);
x=++tot,s[x].a=rd(),s[x].b=rd(),s[x].fa=s[rt].ch[1],s[s[rt].ch[1]].ch[0]=x;
pushup(x),pushup(s[rt].ch[1]),pushup(rt);
}
if(op==1)
{
a=rd(),b=rd(),split(a-1),split(b);
x=find(rt,a),splay(x,rt),y=find(rt,b+2),splay(y,s[x].ch[1]);
s[y].ch[0]=0;
pushup(y),pushup(x);
}
if(op==2)
{
a=rd(),x=find(rt,a+1),splay(x,rt);
printf("%d\n",a-s[s[x].ch[0]].siz+s[x].a);
}
}
return 0;
}//5 3 1 2 3 4 5 0 2 1 4 1 3 8 2 2

【BZOJ3678】wangxz与OJ Splay的更多相关文章

  1. BZOJ3678: wangxz与OJ

    splay缩点. #include<bits/stdc++.h> #define L(t) (t)->c[0] #define R(t) (t)->c[1] #define F ...

  2. BZOJ3678 wangxz与OJ (平衡树 无旋treap)

    题面 维护一个序列,支持以下操作: 1.在某个位置插入一段值连续的数. 2.删除在当前序列位置连续的一段数. 3.查询某个位置的数是多少. 题解 显然平衡树,一个点维护一段值连续的数,如果插入或者删除 ...

  3. bzoj 3678 wangxz与OJ

    3678: wangxz与OJ Time Limit: 10 Sec  Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem.php ...

  4. 【bzoj3678】wangxz与OJ

    Portal -- > bzoj 3678 Solution 这题==真实智力康复qwq 然而众多神犇都说是10min写完的题我..可能写了近1h吧==深深感受到自己的弱小qwq (丢上来是因为 ...

  5. 【BZOJ3678】Wangxz和OJ

    题意: 不想讲 题解: Rope真香! 正解是Splay缩点,访问时再拆成一个序列 代码: //STL dafa good! #include<algorithm> #include< ...

  6. BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常

    Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-”,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和 ...

  7. luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树

    LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...

  8. [BZOJ3678]wangxz与OJ-[Splay一类的平衡树]

    Description 传送门 Solution 直接splay搞定吧..似乎非旋treap也ok? 我已经菜到模板题都写不出来了qaq Code #include<iostream> # ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. 【DataStructure】Linked Data Structures

    Arrayss work well for unordered sequences, and even for ordered squences if they don't change much. ...

  2. QML vs WEB

    UI领域, 如果是桌面应用,QML可以更快速.如果是手机UI,H5绝对占优. 移动设备已经为各行业的HMI的响应性和用户友好性设定了标准.汽车,医疗设备,工业自动化系统和消费电子产品制造商现在希望为其 ...

  3. MySQL的最大连接数

    mysql的最大连接数默认是100, 这个数值对于并发连接很多的数据库应用是远远不够的,当连接请求大于默认连接数后,就会出现无法连接数据库的错误,因此我们需要把它适当调大一些 设置新的MySQL最大连 ...

  4. PHP不能不看的50个细节!

    1. 用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的”函数”(译注:PHP ...

  5. 《FPGA全程进阶---实战演练》第二章之PCB layout注意事项以及投板几点说明

           上一篇博客讲述了各个部分的原理图,那么根据原理图画出PCB,其实PCB是一门很大的学问,想要掌握谈何容易.就笔者在画PCB时的一些注意事项做一些说明.        1.电源部分的电源线 ...

  6. 关于Cocos2d-x中节点的获取

    方法一: 1.在.h文件的属性里面先声明要使用的节点或者变量. private: Label *scorelabel; 2.在.cpp文件中创建并使用这个节点或者变量. scorelabel = La ...

  7. [转载]php设计模式之单例、多例设计模式

    单例(Singleton)模式和不常见的多例(Multiton)模式控制着应用程序中类的数量.如模式名称,单例只能实例化一次,只有一个对象,多例模式可以多次实例化. 基于Singleton的特性,我们 ...

  8. 将ORACLE数据库更改为归档模式;写出步骤

    解答:具体步骤如下: 1),以exp方式在线备份数据库到指定位置: 2),观察当前数据库是以服务器参数文件(spfile)方式启动还是以参数文件(pfile)方式启动: SQL> show pa ...

  9. linux -- ubuntu桌面版安装xampp

    首先,请从www.xampp.org下载最新版XAMPP. 安装 如果是xampp压缩文件 将xampp压缩文件复制到/opt下并解压.如果你计算机没有/opt目录,用 “sudo mkdir/opt ...

  10. Xcode 5.0 编译低版本app

    Xcode 5.0 默认的编译环境是iOS7,编译出来的app,安装到iOS7.0版本以上的手机上,会表现出iOS7.0的风格.兼容不太好的应用,布局上可能会因此乱八七糟. 如果还不想让app升级到i ...