【BZOJ3678】wangxz与OJ Splay
【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
1 2 3 4 5
0 2 1 4
1 3 8
2 2
Sample Output
题解:容易想到用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的更多相关文章
- BZOJ3678: wangxz与OJ
splay缩点. #include<bits/stdc++.h> #define L(t) (t)->c[0] #define R(t) (t)->c[1] #define F ...
- BZOJ3678 wangxz与OJ (平衡树 无旋treap)
题面 维护一个序列,支持以下操作: 1.在某个位置插入一段值连续的数. 2.删除在当前序列位置连续的一段数. 3.查询某个位置的数是多少. 题解 显然平衡树,一个点维护一段值连续的数,如果插入或者删除 ...
- bzoj 3678 wangxz与OJ
3678: wangxz与OJ Time Limit: 10 Sec Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem.php ...
- 【bzoj3678】wangxz与OJ
Portal -- > bzoj 3678 Solution 这题==真实智力康复qwq 然而众多神犇都说是10min写完的题我..可能写了近1h吧==深深感受到自己的弱小qwq (丢上来是因为 ...
- 【BZOJ3678】Wangxz和OJ
题意: 不想讲 题解: Rope真香! 正解是Splay缩点,访问时再拆成一个序列 代码: //STL dafa good! #include<algorithm> #include< ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常
Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-”,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和 ...
- luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树
LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...
- [BZOJ3678]wangxz与OJ-[Splay一类的平衡树]
Description 传送门 Solution 直接splay搞定吧..似乎非旋treap也ok? 我已经菜到模板题都写不出来了qaq Code #include<iostream> # ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- R绘制中国地图,并展示流行病学数据
流行病学的数据讲究“三间分布”,即人群分布.时间分布和空间分布.其中的“空间分布”最好是在地图上展示,才比较清楚.R软件集统计分析与高级绘图于大成,是最适合做这项工作了.关于地图的绘制过程,谢益辉.邱 ...
- 消息中间件系列之Java API操作ActiveMQ
一.依赖 <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activem ...
- spring复习 -day1:Spring简介 、 Spring容器 、 Spring IOC
Spring创建对象方法 创建对象过程: 第一步:添加SpringIOC环境 (1)在WebRoot/WEB-INT/lib文件夹下,引入SpringIOC配置环境的jar包 如图: (2)在sr ...
- nodejs基础 -- NPM 使用介绍
npm:是nodejs的包管理工具,随NodeJS一起安装的,能解决NodeJS代码部署上的很多问题,如: 1.允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2.允许用户从NPM服务器下载 ...
- CentOS 7 Minimal编译安装MySQL5.6
写在前面,编译安装MySQL的优势:平台无关.可设定参数按需安装.安装的MySQL目录独立(方便清楚).更好的平台耦合及运行性能(很多运维的观点):缺点:编译安装较慢. 一.撤换系统防火墙 注:Cen ...
- Python的可变对象与不可变对象。
参考:http://thomaschen2011.iteye.com/blog/1441254 Python基础:Python可变对象和不可变对象 http://blog.jobbo ...
- 【Java面试题】6 判断下面代码是否有问题
1. if(username.equals(“zxx”){} 2. int x = 1; return x==1?true:false; 1.一个变量直接调用equals方法会给程序带来安全隐患,直接 ...
- xpath的数据和节点类型以及XPath中节点匹配的基本方法
XPath数据类型 XPath可分为四种数据类型: 节点集(node-set) 节点集是通过路径匹配返回的符合条件的一组节点的集合.其它类型的数据不能转换为节点集. 布尔值(boolean) ...
- Ubuntu 14.04 Server i386 安装 Oracle11g_11.2.0.3 RAC
文档地址:doc 文档地址:doc
- c++虚函数表 Brew VTBL
参考:http://blog.csdn.net/haoel/article/details/1948051/ BREW VTBL:http://blog.chinaunix.net/uid-51740 ...