算法模板——splay区间反转 2
时间:2022-05-08
本文章向大家介绍算法模板——splay区间反转 2,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树)
这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善
这里面没有像一般二叉排序树那样子用一个参量进行排序,而是直接以中序遍历来构建了一个普通的二叉树(当然也可以把每个点的中序遍历排名视作参量),然后插入的时候就是指定位置插入(这个就比较像是文本插入了)
总之得到了较大的提升,代码优美程度也提高不少
1 var
2 i,j,k,l,m,n,head,tot,ll:longint;
3 a,lef,rig,b,c:array[0..100000] of longint;
4 procedure swap(var x,y:longint);
5 var z:longint;
6 begin
7 z:=x;x:=y;y:=z;
8 end;
9 procedure ext(x:longint); //经典的下推操作,有木有很像线段树呢= =
10 begin
11 if x=0 then exit;
12 if c[x]=0 then exit;
13 if lef[x]<>0 then c[lef[x]]:=1-c[lef[x]];
14 if rig[x]<>0 then c[rig[x]]:=1-c[rig[x]];
15 swap(lef[x],rig[x]);
16 c[x]:=0;
17 end;
18 procedure rt(var x:longint); //lt、rt函数和Treap的极其相似!!!
19 var f,l:longint;
20 begin
21 ext(x);ext(lef[x]);
22 if (x=0) or (lef[x]=0) then exit;
23 f:=x;l:=lef[x];
24 b[lef[x]]:=b[x];
25 b[x]:=1+b[rig[x]]+b[rig[lef[x]]];
26 lef[f]:=rig[l];
27 rig[l]:=f;
28 x:=l;
29 end;
30 procedure lt(var x:longint);
31 var f,r:longint;
32 begin
33 ext(x);ext(rig[x]);
34 if (x=0) or (rig[x]=0) then exit;
35 f:=x;r:=rig[x];
36 b[rig[x]]:=b[x];
37 b[x]:=1+b[lef[x]]+b[lef[rig[x]]];
38 rig[f]:=lef[r];
39 lef[r]:=f;
40 x:=r;
41 end;
42 procedure splay(var head:longint;x:longint); //萌萌哒伸展——而且还可以支持伸展的任意位置,只要设定head的位置,比如像后面的splay(rig[head],x);
43 begin
44 if head=0 then exit;
45 ext(head);
46 if (b[lef[head]]+1)=x then exit;
47 if x<(b[lef[head]]+1) then
48 begin
49 ext(lef[head]);
50 if x=(b[lef[lef[head]]]+1) then rt(head) else
51 if x<(b[lef[lef[head]]]+1) then
52 begin
53 splay(lef[lef[head]],x);
54 rt(head);rt(head);
55 end
56 else
57 begin
58 splay(rig[lef[head]],x-1-b[lef[lef[head]]]);
59 lt(lef[head]);rt(head);
60 end;
61 end
62 else
63 begin
64 ext(rig[head]);
65 x:=x-1-b[lef[head]];
66 if x=(b[lef[rig[head]]]+1) then lt(head) else
67 if x<(b[lef[rig[head]]]+1) then
68 begin
69 splay(lef[rig[head]],x);
70 rt(rig[head]);lt(head);
71 end
72 else
73 begin
74 splay(rig[rig[head]],x-1-b[lef[rig[head]]]);
75 lt(head);lt(head);
76 end;
77 end;
78 end;
79 procedure ins(x,y:longint); //这里的ins操作已经可以支持指定位置插入子伸展树了
80 begin
81 if head=0 then
82 begin
83 head:=y;
84 exit;
85 end;
86 if x=b[head] then
87 begin
88 splay(head,b[head]);
89 rig[head]:=y;
90 inc(b[head],b[y]);
91 end
92 else if x=0 then
93 begin
94 splay(head,1);
95 lef[head]:=y;
96 inc(b[head],b[y]);
97 end
98 else begin
99 splay(head,x);
100 splay(rig[head],x+1);
101 lef[rig[head]]:=y;
102 inc(b[rig[head]],b[y]);
103 inc(b[head],b[y]);
104 end;
105 end;
106 procedure putinvalue(x,y:longint); //加入单个值
107 begin
108 inc(tot);
109 A[TOT]:=x;b[tot]:=1;
110 lef[tot]:=0;rig[tot]:=0;
111 ins(y,tot);
112 end;
113
114 procedure turnover(x,y:longint); //翻转,核心思想还是打标记
115 begin
116 if x=y then exit;
117 if (x=1) and (y=n) then
118 begin
119 c[head]:=1-c[head];
120 exit;
121 end;
122 if (x=1) then
123 begin
124 splay(head,y+1);
125 c[lef[head]]:=1-c[lef[head]];
126 end
127 else if (y=n) then
128 begin
129 splay(head,x-1);
130 c[rig[head]]:=1-c[rig[head]];
131 end
132 else begin
133 splay(head,x-1);
134 splay(rig[head],y-x+2);
135 c[lef[rig[head]]]:=1-c[lef[rig[head]]];
136 end;
137 end;
138 function showtree(head:longint):ansistring;
139 var s1,s2,s3,s4:ansistring;
140 begin
141 if head=0 then exit('');
142 str(a[head],s1);
143 s2:=showtree(lef[head]);
144 s3:=showtree(rig[head]);
145 if c[head]=1 then
146 begin
147 s4:=s2;
148 s2:=s3;
149 s3:=s4;
150 end;
151 if s3<>'' then s3:=','+s3;
152 s2:=s2+s3;
153 if s2<>'' then s2:='('+s2+')';
154 exit(s1+s2);
155 end;
156 procedure putout(x:longint);
157 begin
158 if x=0 then exit;
159 ext(x);
160 putout(lef[x]);
161 write(a[x],' ');
162 putout(rig[x]);
163 end;
164 begin
165 readln(n,m);head:=0;tot:=0;
166 for i:=1 to n do putinvalue(i,i-1);
167 fillchar(c,sizeof(c),0);
168 for i:=1 to m do
169 begin
170 readln(j,k);
171 turnover(j,k);
172 l:=0;
173
174 end;
175 putout(head);
176 writeln;
177 readln;
178 end.
- Linux中MySQL5.6编译安装与MySQL5.7二进制安装步骤
- Nginx服务编译安装、日志功能、状态模块及访问认证模式实操
- 快速入门系列--WebAPI--03框架你值得拥有
- 快速入门系列--MVC--06视图
- 腾讯入局物业管理 欲改造传统服务?
- ExtJs学习笔记(4)_EditorGridPanel(可编辑的网格控件)
- ansible批量管理软件部署及剧本
- 快速入门系列--MVC--02路由
- Javascript生成GUID
- 快速入门系列--MVC--04模型
- 快速入门系列--MVC--03控制器和IOC应用
- ExtJs学习笔记(3)_GridPanel[XML做数据源]
- 快速入门系列--MVC--05行为
- Linux Rsync备份服务介绍及部署守护进程模式
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 你要的干货!信息收集之绕过CDN获取真实网站IP方法总结
- ES聚合操作
- leetcode-easy-array-删除排序数组中的重复项
- SQL注入靶场之SQLiLabs搭建指南
- [OHIF-Viewers]医疗数字阅片-医学影像-redux-token实操(1)
- [OHIF-Viewers]医疗数字阅片-医学影像-屏蔽StudyList病例列表
- Ant Design for Vue的Table组件一列显示多个参数
- 【React】React-router的使用记录
- Blazor带我重玩前端(四)
- Android绘制系统简介
- E: Sub-process /usr/bin/dpkg returned an error code (1) 解决方案
- Linux 如何使用包管理器安装 Node.js
- CSS画图
- R语言聚类算法的应用实例
- Python时间序列选择波动率预测指数收益算法分析案例