题意

给出一个长为$n$序列$[1,2,...,n]$,$m$次操作,每次指定一段区间$[l,r]$,将这段区间翻转,求最终序列

题解

虽然标题是$Splay$,但是我要用$FHQ\ Treap$,考虑先将$[l,r]$这段区间$split$出来($k$即为这段区间)

void split(int o, int k, int &l, int &r) {
if(!o) { l = r = 0; return ; }
if(siz[lc[o]] < k) l = o, split(rc[o], k - siz[lc[o]] - 1, rc[o], r);
else r = o, split(lc[o], k, l, lc[o]);
upt(o);
}//注意这里要按size来split //写在main函数中
while(m--) {
read(x), read(y);
split(rt, y, l, r), split(l, x - 1, l, k);
rev[k] ^= 1; rt = merge(merge(l, k), r);
}//x,y为操作的区间

然后再将这段区间打一个翻转标记(因为平衡树是可以中序遍历输出的吧...,$rev$为翻转标记)

每次涉及到某个节点时,将$rev$标记下放就好了

void pushdown(int o) {
std::swap(lc[o], rc[o]);
if(lc[o]) rev[lc[o]] ^= 1;
if(rc[o]) rev[rc[o]] ^= 1;
rev[o] = 0;
}

#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <algorithm> template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
} const int N = 1e5 + 10;
int n, m, lc[N], rc[N], siz[N], val[N], pri[N], rev[N], tot; inline void upt(int o) { siz[o] = siz[lc[o]] + siz[rc[o]] + 1; }
inline int node(int x) { val[++tot] = x, pri[tot] = rand(), siz[tot] = 1; return tot;}
void pushdown(int o) {
std::swap(lc[o], rc[o]);
if(lc[o]) rev[lc[o]] ^= 1;
if(rc[o]) rev[rc[o]] ^= 1;
rev[o] = 0;
}
void split(int o, int k, int &l, int &r) {
if(!o) { l = r = 0; return ; }
if(rev[o]) pushdown(o);
if(siz[lc[o]] < k) l = o, split(rc[o], k - siz[lc[o]] - 1, rc[o], r);
else r = o, split(lc[o], k, l, lc[o]);
upt(o);
}
int merge(int l, int r) {
if(!l || !r) return l + r;
if(pri[l] < pri[r]) { if(rev[l]) pushdown(l); rc[l] = merge(rc[l], r), upt(l); return l; }
else { if(rev[r]) pushdown(r); lc[r] = merge(l, lc[r]), upt(r); return r; }
}
void print(int o) {
if(!o) return ;
if(rev[o]) pushdown(o);
print(lc[o]), printf("%d ", val[o]), print(rc[o]);
} int main () {
read(n), read(m), srand((unsigned)time(NULL));
int x, y, l, r, k, rt = 0;
for(int i = 1; i <= n; ++i) rt = merge(rt, node(i));
while(m--) {
read(x), read(y);
split(rt, y, l, r), split(l, x - 1, l, k);
rev[k] ^= 1; rt = merge(merge(l, k), r);
} print(rt);
return 0;
}

Luogu P3391 【模板】文艺平衡树(FHQ-Treap)的更多相关文章

  1. P3391 【模板】文艺平衡树FHQ treap

    P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...

  2. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  3. 2021.12.08 平衡树——FHQ Treap

    2021.12.08 平衡树--FHQ Treap http://www.yhzq-blog.cc/fhqtreapzongjie/ https://www.cnblogs.com/zwfymqz/p ...

  4. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  5. Luogu P3835 【模板】可持久化平衡树(fhq Treap)

    P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...

  6. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

  7. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  8. 洛谷.3391.文艺平衡树(fhq Traep)

    题目链接 //注意反转时先分裂r,因为l,r是针对整棵树的排名 #include<cstdio> #include<cctype> #include<algorithm& ...

  9. 【洛谷P3391】文艺平衡树——Splay学习笔记(二)

    题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...

  10. FHQ Treap及其可持久化与朝鲜树式重构

    FHQ Treap,又称无旋treap,一种不基于旋转机制的平衡树,可支持所有有旋treap.splay等能支持的操作(只有在LCT中会比splay复杂度多一个log).最重要的是,它是OI中唯一一种 ...

随机推荐

  1. Linux和windows下检查jsp后门文件的方法

    Linux下: find . -name "*.jsp" | xargs egrep -liw "createNewFile| File\(| File |applica ...

  2. Linux命令之pstree - 以树状图显示进程间的关系

    pstree命令以树状图显示进程间的关系(display a tree of processes).ps命令可以显示当前正在运行的那些进程的信息,但是对于它们之间的关系却显示得不够清晰.在Linux系 ...

  3. 基本控件文档-UIButton属性---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...

  4. Desert King(POJ2728+最优比率生成树+二分)

    题目链接:http://poj.org/problem?id=2728 题目: 题意:求一颗生成树,使得费用与距离的比值最小,其中距离等于两点之间的平面欧拉距离,费用为z坐标之差. 思路: 由上图我们 ...

  5. Codeforces Round #482 (Div. 2) B题

    题目链接:http://codeforces.com/contest/979/problem/B B. Treasure Hunt time limit per test1 second memory ...

  6. PAT L2-017. 人以群分

    题目链接:https://www.patest.cn/contests/gplt/L2-017 题目: 社交网络中我们给每个人定义了一个“活跃度”,现希望根据这个指标把人群分为两大类,即外向型(out ...

  7. Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别【转】

    转自:http://www.th7.cn/system/lin/201606/167750.shtml 我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一 ...

  8. 图论-最近公共祖先-离线Tarjan算法

    有关概念: 最近公共祖先(LCA,Lowest Common Ancestors):对于有根树T的两个结点u.v,最近公共祖先表示u和v的深度最大的共同祖先. Tarjan是求LCA的离线算法(先存储 ...

  9. Tomcat+Apache 负载均衡

    1.JDK1.8和Tomcat7.0不兼容,支持Tomcat8.0. 集群架构图: 2.负载均衡:负载的基础是集群,集群就是一组连在一起的计算机,从外部看它是一个系统,各节点可以是不同的操作系统或不同 ...

  10. 关于ASP .NET Core在跨平台的linux ubuntun,SUSE ,Mac OS的发布的相关平台操作

    https://www.microsoft.com/net/learn/get-started/linuxopensuse