https://www.luogu.org/problem/P3391

使用无旋Treap维护序列,注意的是按顺序插入的序列,所以Insert实际上简化成直接root和Merge合并,但是假如要在序列中插入某个数,则要SplitRank到正确的位置。

注意SplitRank的写法以及Pushdown的东西。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls(p) ch[p][0]
#define rs(p) ch[p][1] const int MAXN = 200000 + 5;
int val[MAXN], ch[MAXN][2], rnd[MAXN], siz[MAXN], tot, root;
bool rev[MAXN]; void Init() {
root = 0, tot = 0;
} inline void PushUp(int p) {
siz[p] = siz[ls(p)] + siz[rs(p)] + 1;
} inline void PushDown(int p) {
if(rev[p]) {
swap(ls(p), rs(p));
if(ls(p))
rev[ls(p)] ^= 1;
if(rs(p))
rev[rs(p)] ^= 1;
rev[p] = 0;
}
} void SplitRank(int p, int rk, int &x, int &y) {
if(!p) {
x = y = 0;
return;
}
PushDown(p);
if(rk <= siz[ls(p)]) {
y = p;
SplitRank(ls(p), rk, x, ls(p));
PushUp(y);
} else {
x = p;
SplitRank(rs(p), rk - siz[ls(p)] - 1, rs(p), y);
PushUp(x);
}
} int Merge(int x, int y) {
if(!x || !y)
return x | y;
if(rnd[x] < rnd[y]) {
PushDown(x);
rs(x) = Merge(rs(x), y);
PushUp(x);
return x;
} else {
PushDown(y);
ls(y) = Merge(x, ls(y));
PushUp(y);
return y;
}
} int NewNode(int v) {
int p = ++tot;
ch[p][0] = ch[p][1] = 0;
val[p] = v, rnd[p] = rand();
siz[p] = 1;
return p;
} void Insert(int &root, int v) {
root = Merge(root, NewNode(v));
} void Reverse(int &root, int l, int r) {
int x = 0, y = 0, z = 0;
SplitRank(root, l - 1, x, y);
SplitRank(y, r + 1 - l, y, z);
rev[y] ^= 1;
root = Merge(Merge(x, y), z);
} vector<int> ans; void Show(int p) {
PushDown(p);
if(ls(p))
Show(ls(p));
ans.push_back(val[p]);
if(rs(p))
Show(rs(p));
} int d[MAXN], f[MAXN], a[MAXN]; int u2topo[MAXN], cnttopo, topo2u[MAXN]; struct Query {
int u, k, ans, id;
bool operator<(const Query& q)const {
return u2topo[u] < u2topo[q.u];
}
} que[MAXN]; struct cmp {
bool operator()(const Query& q1, const Query& q2)const {
return q1.id < q2.id;
}
}; int que2[MAXN];
int front, back; int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int n, q;
while(~scanf("%d%d", &n, &q)) {
Init();
for(int i = 1; i <= n; ++i) {
Insert(root, i);
}
for(int i = 1; i <= q; ++i) {
int l, r;
scanf("%d%d", &l, &r);
Reverse(root, l, r);
}
ans.clear();
Show(root);
for(int i = 0; i < ans.size(); ++i)
printf("%d%c", ans[i], " \n"[i == ans.size() - 1]);
}
return 0;
}

最新文章

  1. iOS网络4——Reachability检测网络状态
  2. 【Android】Android ObjectAnimator动画初识、模仿
  3. Vcenter server 5.5安装部署
  4. CCF真题之命令行选项
  5. VS2012 ActiveX控件_D接口添加方法事项
  6. 委托的lambda表达式
  7. ubuntu连接无线网
  8. Regex阅读笔记(一)之入门
  9. Hibernate 映射字段问题[ImprovedNamingStrategy]
  10. C标准I/O建立一个文件仓库
  11. docker搭建zabbix
  12. 微信小程序之跳转、请求、带参数请求小例子
  13. Spring mvc session cookie实现自动登录
  14. 安装和使用Docker(Windows7)
  15. mybatis02--增删改查
  16. sublime text 3 显示空格和Tab
  17. AS(Android Studio)不停的updating indices
  18. tf.assign,tf.assign_add,tf.assign_sub
  19. Java SPI机制简介
  20. 提升HTML5的性能体验系列之三 流畅下拉刷新和上拉

热门文章

  1. os模块 sys模块 json/pickle 模块 logging模块
  2. [转帖]ssh 远程执行命令
  3. Zookeeper实现哨兵机制
  4. SonarQube规则之bug类型
  5. font-size:0; 消除空白间隙
  6. CF643E Bear and Destroying Subtrees
  7. Educational Codeforces Round 16 D. Two Arithmetic Progressions (不互质中国剩余定理)
  8. RHEL6 kernel bug在hadoop上的测试
  9. mui初级入门教程(五)— 聊聊即时通讯(IM),基于环信 web im SDK
  10. SpringBoot系列:二、SpringBoot的配置文件