实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树)

这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善

这里面没有像一般二叉排序树那样子用一个参量进行排序,而是直接以中序遍历来构建了一个普通的二叉树(当然也可以把每个点的中序遍历排名视作参量),然后插入的时候就是指定位置插入(这个就比较像是文本插入了)

总之得到了较大的提升,代码优美程度也提高不少

 var
i,j,k,l,m,n,head,tot,ll:longint;
a,lef,rig,b,c:array[..] of longint;
procedure swap(var x,y:longint);
var z:longint;
begin
z:=x;x:=y;y:=z;
end;
procedure ext(x:longint); //经典的下推操作,有木有很像线段树呢= =
begin
if x= then exit;
if c[x]= then exit;
if lef[x]<> then c[lef[x]]:=-c[lef[x]];
if rig[x]<> then c[rig[x]]:=-c[rig[x]];
swap(lef[x],rig[x]);
c[x]:=;
end;
procedure rt(var x:longint); //lt、rt函数和Treap的极其相似!!!
var f,l:longint;
begin
ext(x);ext(lef[x]);
if (x=) or (lef[x]=) then exit;
f:=x;l:=lef[x];
b[lef[x]]:=b[x];
b[x]:=+b[rig[x]]+b[rig[lef[x]]];
lef[f]:=rig[l];
rig[l]:=f;
x:=l;
end;
procedure lt(var x:longint);
var f,r:longint;
begin
ext(x);ext(rig[x]);
if (x=) or (rig[x]=) then exit;
f:=x;r:=rig[x];
b[rig[x]]:=b[x];
b[x]:=+b[lef[x]]+b[lef[rig[x]]];
rig[f]:=lef[r];
lef[r]:=f;
x:=r;
end;
procedure splay(var head:longint;x:longint); //萌萌哒伸展——而且还可以支持伸展的任意位置,只要设定head的位置,比如像后面的splay(rig[head],x);
begin
if head= then exit;
ext(head);
if (b[lef[head]]+)=x then exit;
if x<(b[lef[head]]+) then
begin
ext(lef[head]);
if x=(b[lef[lef[head]]]+) then rt(head) else
if x<(b[lef[lef[head]]]+) then
begin
splay(lef[lef[head]],x);
rt(head);rt(head);
end
else
begin
splay(rig[lef[head]],x--b[lef[lef[head]]]);
lt(lef[head]);rt(head);
end;
end
else
begin
ext(rig[head]);
x:=x--b[lef[head]];
if x=(b[lef[rig[head]]]+) then lt(head) else
if x<(b[lef[rig[head]]]+) then
begin
splay(lef[rig[head]],x);
rt(rig[head]);lt(head);
end
else
begin
splay(rig[rig[head]],x--b[lef[rig[head]]]);
lt(head);lt(head);
end;
end;
end;
procedure ins(x,y:longint); //这里的ins操作已经可以支持指定位置插入子伸展树了
begin
if head= then
begin
head:=y;
exit;
end;
if x=b[head] then
begin
splay(head,b[head]);
rig[head]:=y;
inc(b[head],b[y]);
end
else if x= then
begin
splay(head,);
lef[head]:=y;
inc(b[head],b[y]);
end
else begin
splay(head,x);
splay(rig[head],x+);
lef[rig[head]]:=y;
inc(b[rig[head]],b[y]);
inc(b[head],b[y]);
end;
end;
procedure putinvalue(x,y:longint); //加入单个值
begin
inc(tot);
A[TOT]:=x;b[tot]:=;
lef[tot]:=;rig[tot]:=;
ins(y,tot);
end; procedure turnover(x,y:longint); //翻转,核心思想还是打标记
begin
if x=y then exit;
if (x=) and (y=n) then
begin
c[head]:=-c[head];
exit;
end;
if (x=) then
begin
splay(head,y+);
c[lef[head]]:=-c[lef[head]];
end
else if (y=n) then
begin
splay(head,x-);
c[rig[head]]:=-c[rig[head]];
end
else begin
splay(head,x-);
splay(rig[head],y-x+);
c[lef[rig[head]]]:=-c[lef[rig[head]]];
end;
end;
function showtree(head:longint):ansistring;
var s1,s2,s3,s4:ansistring;
begin
if head= then exit('');
str(a[head],s1);
s2:=showtree(lef[head]);
s3:=showtree(rig[head]);
if c[head]= then
begin
s4:=s2;
s2:=s3;
s3:=s4;
end;
if s3<>'' then s3:=','+s3;
s2:=s2+s3;
if s2<>'' then s2:='('+s2+')';
exit(s1+s2);
end;
procedure putout(x:longint);
begin
if x= then exit;
ext(x);
putout(lef[x]);
write(a[x],' ');
putout(rig[x]);
end;
begin
readln(n,m);head:=;tot:=;
for i:= to n do putinvalue(i,i-);
fillchar(c,sizeof(c),);
for i:= to m do
begin
readln(j,k);
turnover(j,k);
l:=; end;
putout(head);
writeln;
readln;
end.

算法模板——splay区间反转 2的更多相关文章

  1. 算法模板——splay区间反转 1

    实现的功能:将序列区间反转,并维护 详见BZOJ3223 var i,j,k,l,m,n,head,a1,a2:longint; s1:ansistring; a,b,c,d,fat,lef,rig: ...

  2. Splay 区间反转

    同样的,我们以一道题来引入. 传送门 这次的任务比较少,只要求进行区间反转.区间反转? 这个好像用啥都是O(n)的吧……(这次vector,set也救不了你了) 我们来使用splay解决这个问题.我们 ...

  3. hdu 1890 Robotic Sort(splay 区间反转+删点)

    题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...

  4. [bzoj3223]文艺平衡树(splay区间反转模板)

    解题关键:splay模板题. #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  5. HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...

  6. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  7. 2018牛客网暑期ACM多校训练营(第三场) H - Shuffle Cards - [splay伸展树][区间移动][区间反转]

    题目链接:https://www.nowcoder.com/acm/contest/141/C 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

  8. 算法笔记--Splay && Link-Cut-Tree

    Splay 参考:https://tiger0132.blog.luogu.org/slay-notes 普通模板: ; ], val[N], cnt[N], fa[N], sz[N], lazy[N ...

  9. hdu1890 伸展树(区间反转)

    对于大神来说这题是水题.我搞这题花了快2天. 伸展树的优点有什么,就是树不管你怎么旋转序列是不会改变得,并且你要使区间反转,只要把第k大的点转到根结点,那么它的左子树就是要交换的区间[l,r),然后交 ...

随机推荐

  1. 验证浏览器是否安装已flash插件的js脚本

    function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //flash版本 if(document ...

  2. 使用XML布局文件和Java代码混合控制UI界面

    完全使用Java代码来控制UI界面不仅烦琐.而且不利于解耦:而完全利用XML布局文件来控制UI界面虽然方便.便捷,但难免有失灵活.因此有些时候,可能需要混合使用XML布局文件和代码来控制UI界面. 当 ...

  3. C++ 常量类型 const 详解

    1.什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const? const 推出的初始目的 ...

  4. Spring4 Hibernate4 Struts2在WebLogic 10.3.3上面部署

    折腾了4天,终于可以部署了: 1,lib下面的包: antlr-2.7.7.jarasm-5.0.2.jarasm-commons-5.0.2.jarasm-tree-5.0.2.jarc3p0-0. ...

  5. 利用Flare3D和Stage3D创建3D

    Flare3D 是一款功能强大的引擎,它使得 Flash 中的 3D 内容管理变得更为简便. 它的设计宗旨是提供一个完美的开发工作流程,以便你能够获得事半功倍的效果. 本教程侧重讨论在 Flash 中 ...

  6. Excel里函数中的万金油,你确定不要点进来看看?

    Excel里函数中的万金油,你确定不要点进来看看? 来源:EXCELHome Excel里有个号称"万能"的函数组合,这个函数组合就是INDEX+SMALL+IF,很多应用场合都能 ...

  7. C++从string中删除所有的某个特定字符

    C++中要从string中删除所有某个特定字符, 可用如下代码 str.erase(std::remove(str.begin(), str.end(), 'a'), str.end()); 其中, ...

  8. 2017了,回家前 "年末" 分享:下雨,飘雪,红包雨,碰撞球,自定义View

    (本博客为原创:http://www.cnblogs.com/linguanh/) 目录: 效果展示 感想 代码拆解 开源地址 效果展示 有没有兴趣继续看下去,直接看下"颜值"是第 ...

  9. 计算机程序的思维逻辑 (64) - 常见文件类型处理: 属性文件/CSV/EXCEL/HTML/压缩文件

    对于处理文件,我们介绍了流的方式,57节介绍了字节流,58节介绍了字符流,同时,也介绍了比较底层的操作文件的方式,60节介绍了随机读写文件,61节介绍了内存映射文件,我们也介绍了对象的序列化/反序列化 ...

  10. 报表学习总结(一)——ASP.NET 水晶报表(Crystal Reports)的简单使用

    一.水晶报表简介 Crystal Reports(水晶报表)是一款商务智能(BI)软件,主要用于设计及产生报表.水晶报表是业内最专业.功能最强的报表系统,它除了强大的报表功能外.最大的优势是实现了与绝 ...