poj3580
区间操作的究极题,我们一个个来分析
其实只有insert,delete,revolve三种没讲过
insert 先把x旋到根,一开始我比较SB的,准备把新节点插入到右子树的最左节点,这显然很烦
好的方法是,直接在根和右孩子之间插入即可,相当于right[new]=right[root] right[root]=new
然后维护一下new和root即可即可
delete 我一开始使用的是杨思雨大神splay论文中的方法,但是好像很烦
后来发现,一个比较简洁的做法,先把x的后继旋到根,然后把x旋到根的儿子的位置上(显然是左孩子)
显然x是不含有右子树的,所以,直接删去x即可(就是x的左子树直接与根相连
revolve 这是这道题最难的一个操作了,感觉自己写的也不是很好,还是讲讲方法吧
首先这个操作的本质是[l,k][k+1,r]这两个区间交换位置
考虑到假如在k和k+1中间有一个中间点,那么我只要把中间点旋到区间的根上然后直接交换左右子树即可
但是是不存在的,所以我们考虑先把k作为这个中间点,交换完左右子树后再把k插入到区间最后
也就是先把k旋到区间根上,然后交换左右子树,然后把k节点删去,再把他插入区间末尾
如果l=k,就不需要删去插入这一步了,感觉写得挺麻烦的
const inf=; var son:array[..,..] of longint;
count,fa,a,lazy,mina:array[..] of longint;
v:array[..] of boolean;
n,m,i,x,y,z,p,root:longint;
s:string;
ch:char; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure add(x,y:longint);
begin
mina[x]:=mina[x]+y;
a[x]:=a[x]+y;
lazy[x]:=lazy[x]+y;
end; procedure change(x:longint);
begin
swap(son[x,],son[x,]);
v[x]:=not v[x];
end; procedure update(x:longint);
begin
count[x]:=count[son[x,]]+count[son[x,]]+;
mina[x]:=min(a[x],min(mina[son[x,]],mina[son[x,]]));
end; procedure push(x:longint);
var l,r:longint;
begin
l:=son[x,];
r:=son[x,];
if lazy[x]<> then
begin
if l<>- then add(l,lazy[x]);
if r<>- then add(r,lazy[x]);
lazy[x]:=;
end;
if v[x] then
begin
if l<>- then change(l);
if r<>- then change(r);
v[x]:=false;
end;
end; procedure rotate(x,w:longint);
var y:longint;
begin
push(x);
y:=fa[x];
if fa[y]<>- then
begin
if son[fa[y],]=y then son[fa[y],]:=x
else son[fa[y],]:=x;
end
else root:=x;
fa[x]:=fa[y];
son[y,-w]:=son[x,w];
if son[x,w]<>- then fa[son[x,w]]:=y;
son[x,w]:=y;
fa[y]:=x;
update(y);
update(x);
end; procedure splay(x,f:longint);
var y:longint;
begin
while fa[x]<>f do
begin
y:=fa[x];
if fa[y]=f then
begin
if son[y,]=x then rotate(x,)
else rotate(x,);
end
else begin
if son[fa[y],]=y then
begin
if son[y,]=x then rotate(y,) else rotate(x,);
rotate(x,);
end
else begin
if son[y,]=x then rotate(x,) else rotate(y,);
rotate(x,);
end;
end;
end;
end; function find(k:longint):longint;
var p:longint;
begin
p:=root;
while true do
begin
push(p);
if count[son[p,]]+=k then exit(p);
if count[son[p,]]+>k then p:=son[p,]
else begin
k:=k-count[son[p,]]-;
p:=son[p,];
end;
end;
end; procedure getrange; //提取区间
begin
x:=find(x);
y:=find(y+);
splay(x,-);
splay(y,x);
end; procedure insert(x,p:longint); // p是新插入节点
begin
splay(x,-);
son[p,]:=son[x,];
fa[son[x,]]:=p;
son[x,]:=p;
fa[p]:=x;
update(p);
update(x);
end; procedure delete(x,p:longint); //p是x的后继节点
begin
splay(p,-);
splay(x,p);
if son[x,]<>- then fa[son[x,]]:=p;
son[p,]:=son[x,];
son[x,]:=-;
son[x,]:=-;
fa[x]:=-;
update(p);
end; function build(l,r:longint):longint;
var m:longint;
begin
m:=(l+r) shr ;
build:=m;
if m->=l then
begin
son[m,]:=build(l,m-);
fa[son[m,]]:=m;
end;
if m+<=r then
begin
son[m,]:=build(m+,r);
fa[son[m,]]:=m;
end;
update(m);
end; procedure revolve;
var l,r,p,last:longint;
begin
last:=find(y-z+); // 交换[x,y-z][y-z+,y];
if y-z=x then
begin
getrange;
splay(last,y);
swap(son[last,],son[last,]);
end
else begin
l:=x;
r:=y;
getrange;
splay(last,y);
swap(son[last,],son[last,]);
//交换完后,中间点对应区间上的点也不同了
p:=find(l+z+); //注意这里两处找位置对应树上的点,交换删除后,同一位置对应树上的点会不不同
delete(last,p);
p:=find(r);
insert(p,last);
end;
end; begin
readln(n);
fillchar(son,sizeof(son),);
fillchar(fa,sizeof(fa),);
for i:= to n do
readln(a[i]);
for i:=- to n+ do
mina[i]:=inf;
count[-]:=;
a[-]:=inf;
a[]:=inf;
a[n+]:=inf;
root:=build(,n+);
inc(n);
readln(m);
for i:= to m do
begin
read(ch);
s:='';
while ch<>' ' do
begin
s:=s+ch;
read(ch);
end;
if s='ADD' then
begin
readln(x,y,z);
getrange;
add(son[y,],z);
end
else if s='REVERSE' then
begin
readln(x,y);
getrange;
change(son[y,]);
end
else if s='REVOLVE' then
begin
readln(x,y,z);
z:=z mod (y-x+); //注意
if z<> then revolve;
end
else if s='INSERT' then
begin
readln(x,y);
x:=find(x+);
inc(n); mina[n]:=y; a[n]:=y; count[n]:=;
insert(x,n);
end
else if s='DELETE' then
begin
readln(x);
p:=find(x+);
x:=find(x+);
delete(x,p);
end
else begin
readln(x,y);
getrange;
writeln(mina[son[y,]]);
end;
end;
end.
poj3580的更多相关文章
- poj3580 splay树 REVOVLE循环
SuperMemo Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12795 Accepted: 3989 Case T ...
- poj3580 伸展树(区间翻转 区间搬移 删除结点 加入结点 成段更新)
好题.我做了很久,学了大牛们的区间搬移.主要的代码都有注释. #include<cstdio> #include<cstring> #include<iostream&g ...
- 【POJ3580】【splay版】SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant i ...
- 【POJ3580】【块状链表】SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant i ...
- POJ3580 SuperMemo splay伸展树,区间操作
题意:实现一种数据结构,支持对一个数列的 6 种操作:第 x 个数到第 y 个数之间的数每个加 D:第 x 个数到第 y 个数之间全部数翻转:第 x 个数到第 y 个数之间的数,向后循环流动 c 次, ...
- POJ3580 SuperMemo
Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to pl ...
- Poj3580 Super Memo(FHQ-Treap)
题面 题解 对于操作$1$,我们可以对于每个节点打一个$add$标记,下放就行了 对于操作2,可以参考这篇题解的上一篇,不赘述 对于操作4,可以将区间裂成两部分,然后再插入合并 对于操作5,可以将区间 ...
- poj3580 序列之王 fhqtreap
fhqtreap的写法 操作其实都差不多哇 #include<cstdio> #include<cstring> #include<algorithm> using ...
- POJ3580:SuperMemo
浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...
随机推荐
- 用标准版的Eclipse搭建PHP环境
用标准版的Eclipse搭建PHP环境 ——@梁WP 摘要:用标准版的Eclipse搭建PHP环境. 一.下载Eclipse的PHP插件 百度搜索phpeclipse,看到某条结果是带有SourceF ...
- 在sql2008的实例 中 编写存储过程 读取 版本为sql2005 的实例 中的某个数据库里的数据
--创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvl ...
- DEDE自带的采集功能,标题太短的解决方法
DEDE自带的采集功能,标题太短获取不全的解决方法搜索了好多之后,终于还是在dede的官方论坛找到了答案.增加采集标题长度:255 目的:原标题长度太小,影响文件采集⑴修改系统参数设置(文档标题最大 ...
- java反射的应用+mybatis+spring动态生成数据库表
最近接触了一个类似于代码生成工具的活.思路是,通过java的反射机制得到类的字段和字段类型, 从而可以创建一个map集合存储表名(由类名决定的特殊结构字符串),表字段(由类变量确定),表字段类型(由变 ...
- Java 读取Properties 配置文件
方法一,使用 io 包中的 BufferedInputStream 以及 FileInputStream读入文件转成字符流,然后使用 lang 包中 的 Properties 的 load 方法进行读 ...
- Mybatis的学习总结:mybatis的入门介绍
一.myBatis简述 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...
- zoom与transform:scale的区别
一. zoom特性 1. zoom是IE的私有属性,但目前除Firefox不支持外,其他浏览器支持尚好. 2.定义: zoom即变焦,可改变元素尺寸,属于真实尺寸.zoom:百分值/数值/normal ...
- CSS3 文本装饰
浏览器对CSS3文本特性的支持情况,如下表所示: 浏览器 text-shadow text-overflow word-wrap hyphens Opera 9.5+ 9+.带前缀-o- 10.5+ ...
- dx环境搭建
我使用的是vs2012+DXSDK_Jun10 DXSDK_Jun10下载地址http://download.microsoft.com/download/A/E/7/AE743F1F-632B-48 ...
- AngularJS测试框架 karma备忘
AngularJS测试框架karma安装 安装karma $ --save-dev 安装karma组件 $ npm install karma-jasmine karma-chrome-launche ...