题意

给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$


Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+1$ Splay到根节点的右儿子,那么根节点右儿子的左儿子就对应区间$[L,R]$,对于反转操作,通过懒操作下放

代码

#include <bits/stdc++.h>
#define inf 0x7f7f7f7f
using namespace std;
const int N = 500005;
int ch[N][2], fa[N], key[N], lazy[N], sz[N];
int root, tot;
inline int get(int x) {return ch[fa[x]][1] == x;} // left is 0, right is 1
inline void pushup(int x) {
sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}
inline void pushdown(int x) {
if(lazy[x]) {
lazy[x] = 0;
swap(ch[x][0], ch[x][1]);
lazy[ch[x][0]] ^= 1; lazy[ch[x][1]] ^= 1;
}
}
inline void rotate(int x) {
int f = fa[x], ff = fa[f], which = get(x);
pushdown(f); pushdown(x);
ch[f][which] = ch[x][which ^ 1];
fa[ch[f][which]] = f;
ch[x][which ^ 1] = f;
fa[f] = x; fa[x] = ff;
if(ff) ch[ff][ch[ff][1] == f] = x;
pushup(f); pushup(x);
}
inline void splay(int x, int target) {
while(fa[x] != target) {
if(fa[fa[x]] != target) {
rotate((get(x) == get(fa[x])) ? fa[x] : x);
}
rotate(x);
}
if(!target) root = x;
}
inline int get_kth(int x, int k) {
if(!x) return 0;
while(1) {
pushdown(x);
if(k == sz[ch[x][0]] + 1) break;
if(k > sz[ch[x][0]] + 1) {
k -= sz[ch[x][0]] + 1; x = ch[x][1];
}else x = ch[x][0];
}
return x;
}
inline int newnode(int v, int f) {
int x = ++tot;
ch[x][0] = ch[x][1] = 0; fa[x] = f;
key[x] = v; sz[x] = 1; lazy[x] = 0;
return x;
}
int build(int l, int r, int f) {
if(l > r) return 0;
int mid = (l + r) / 2;
int x = newnode(mid, f);
ch[x][0] = build(l, mid - 1, x);
ch[x][1] = build(mid + 1, r, x);
pushup(x);
return x;
}
inline void init(int x) {root = tot = 0; root = build(0, x + 1, 0);}
inline void cut(int l, int r, int c) {
splay(get_kth(root, l), 0); splay(get_kth(root, r + 2), root);
int tmp = ch[ch[root][1]][0];
ch[ch[root][1]][0] = 0;
pushup(ch[root][1]); pushup(root);
splay(get_kth(root, c + 1), 0); splay(get_kth(root, c + 2), root);
fa[tmp] = ch[root][1];
ch[ch[root][1]][0] = tmp;
pushup(ch[root][1]); pushup(root);
}
inline void filp(int l, int r) {
splay(get_kth(root, l), 0); splay(get_kth(root, r + 2), root);
lazy[ch[ch[root][1]][0]] ^= 1;
pushup(ch[root][1]); pushup(root);
}
int n, m, a, b, c;
int cnt;
void out(int x){
if (!x) return;
pushdown(x);
out(ch[x][0]);
if (key[x] >= 1 && key[x] <= n) {
cnt++;
printf("%d", key[x]);
if (cnt < n) printf(" ");
else puts("");
}
out(ch[x][1]);
}
char opt[20];
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == -1 && m == -1) break;
init(n);
for(int i = 1; i <= m ;++i) {
scanf("%s", opt);
if(opt[0] == 'C') {
scanf("%d%d%d", &a, &b, &c); cut(a, b, c);
}else scanf("%d%d", &a, &b, &c), filp(a, b);
}
cnt = 0; out(root);
}
return 0;
}

最新文章

  1. JAVA 虚拟机钩子
  2. 表单填写示例(通过JavaScript访问DOM)
  3. MULTITHREADING AND CHIP MULTIPROCESSORS
  4. 【Xamarin报错】 COMPILETODALVIK : UNEXPECTED TOP-LEVEL error java.lang.OutOfMemoryError: Java heap space
  5. 常用HTML正则
  6. HDU 5818 Joint Stacks
  7. Qt: 访问容器(三种方法,加上for循环就四种了)good
  8. ASP.NET(C#) GridView (编辑、删除、更新、取消)
  9. sketchup 导出 fbx文件 单位 错误
  10. Android 开发之网易云音乐(或QQ音乐)的播放界面转盘和自定义SeekBar的实现
  11. Sky数 2097
  12. 深入理解viewport(转)
  13. 利用HTML5的window.postMessage实现跨域通信
  14. 使用Dapper操作Mysql数据库
  15. jQuery 文档操作方法
  16. 51 NOD 1238 最小公倍数之和 V3
  17. 行为驱动:Cucumber + Selenium + Java(二) - extentreports 测试报告+jenkins持续集成
  18. html5中视频播放问题总结
  19. Django中Model-Form验证
  20. 细说spring事务配置属性

热门文章

  1. Android 进程间通信——AIDL
  2. 浅谈对TDD的看法
  3. SQL EXISTS 与 IN
  4. win7 iis6怎么部署.net网站
  5. (一)关于jQuery的网上资源
  6. jquery垂直滚动插件一个参数用于设置速度,兼容ie6
  7. Windows 10正式版历代记:Version 1709、Build 16299都是什么鬼?
  8. 新手学习JSP+Servlet笔记一
  9. PythonCookBook笔记——函数
  10. 解决Oracle用户被锁定的方法