洛谷 - P3391 【模板】文艺平衡树(Splay) - 无旋Treap
2024-10-07 10:11:24
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;
}
最新文章
- iOS网络4——Reachability检测网络状态
- 【Android】Android ObjectAnimator动画初识、模仿
- Vcenter server 5.5安装部署
- CCF真题之命令行选项
- VS2012 ActiveX控件_D接口添加方法事项
- 委托的lambda表达式
- ubuntu连接无线网
- Regex阅读笔记(一)之入门
- Hibernate 映射字段问题[ImprovedNamingStrategy]
- C标准I/O建立一个文件仓库
- docker搭建zabbix
- 微信小程序之跳转、请求、带参数请求小例子
- Spring mvc session cookie实现自动登录
- 安装和使用Docker(Windows7)
- mybatis02--增删改查
- sublime text 3 显示空格和Tab
- AS(Android Studio)不停的updating indices
- tf.assign,tf.assign_add,tf.assign_sub
- Java SPI机制简介
- 提升HTML5的性能体验系列之三 流畅下拉刷新和上拉
热门文章
- os模块 sys模块 json/pickle 模块 logging模块
- [转帖]ssh 远程执行命令
- Zookeeper实现哨兵机制
- SonarQube规则之bug类型
- font-size:0; 消除空白间隙
- CF643E Bear and Destroying Subtrees
- Educational Codeforces Round 16 D. Two Arithmetic Progressions (不互质中国剩余定理)
- RHEL6 kernel bug在hadoop上的测试
- mui初级入门教程(五)— 聊聊即时通讯(IM),基于环信 web im SDK
- SpringBoot系列:二、SpringBoot的配置文件