您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

N,M<=100000

Sample Output4 3 2 1 5

Hint

Input

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n

Output

输出一行n个数字,表示原始序列经过m次变换后的结果

Sample Input5 3

1 3

1 3

1 4

 
Splay Tree ,和上道题一样,我们的kth 返回的序列的第k个数;
然后中序遍历即可得到我们翻转后的序列;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#pragma GCC optimize(2)
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++) inline ll rd() {
ll x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
} ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; } /*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return a;
}
ans = exgcd(b, a%b, x, y);
ll t = x; x = y; y = t - a / b * y;
return ans;
}
*/ ll qpow(ll a, ll b, ll c) {
ll ans = 1;
a = a % c;
while (b) {
if (b % 2)ans = ans * a%c;
b /= 2; a = a * a%c;
}
return ans;
} struct splay {
int fa, ch[2], size;
int lazy, rev, maxx, value;
}Sp[maxn]; int n, m, root, a[maxn];
void pushup(int rt) {
Sp[rt].size = Sp[Sp[rt].ch[0]].size + Sp[Sp[rt].ch[1]].size + 1;
Sp[rt].maxx = max(Sp[rt].value, max(Sp[Sp[rt].ch[0]].maxx, Sp[Sp[rt].ch[1]].maxx));
} void pushdown(int rt) {
if (Sp[rt].lazy) {
if (Sp[rt].ch[0]) {
Sp[Sp[rt].ch[0]].lazy += Sp[rt].lazy;
Sp[Sp[rt].ch[0]].maxx += Sp[rt].lazy;
Sp[Sp[rt].ch[0]].value += Sp[rt].lazy;
}
if (Sp[rt].ch[1]) {
Sp[Sp[rt].ch[1]].lazy += Sp[rt].lazy;
Sp[Sp[rt].ch[1]].maxx += Sp[rt].lazy;
Sp[Sp[rt].ch[1]].value += Sp[rt].lazy;
}
Sp[rt].lazy = 0;
}
if (Sp[rt].rev) {
if (Sp[rt].ch[0]) {
Sp[Sp[rt].ch[0]].rev ^= 1;
swap(Sp[Sp[rt].ch[0]].ch[0], Sp[Sp[rt].ch[0]].ch[1]);
}
if (Sp[rt].ch[1]) {
Sp[Sp[rt].ch[1]].rev ^= 1;
swap(Sp[Sp[rt].ch[1]].ch[0], Sp[Sp[rt].ch[1]].ch[1]);
}
Sp[rt].rev = 0;
}
} int id(int x) {
return Sp[Sp[x].fa].ch[1] == x;
}
void link(int son, int fa, int k) {
Sp[son].fa = fa; Sp[fa].ch[k] = son;
} void rotate(int x) {
int y = Sp[x].fa;
int z = Sp[y].fa;
int yk = id(x);
int zk = id(y);
int b = Sp[x].ch[yk ^ 1];
link(b, y, yk); link(y, x, yk ^ 1);
link(x, z, zk);
pushup(y); pushup(x);
} void SPLAY(int x, int aim) {
while (Sp[x].fa != aim) {
int y = Sp[x].fa;
int z = Sp[y].fa;
if (z != aim)id(x) == id(y) ? rotate(y) : rotate(x);
rotate(x);
}
if (aim == 0)root = x;
} int kth(int k) {
int now = root;
while (1) {
pushdown(now);
int left = Sp[now].ch[0];
if (Sp[left].size + 1 < k) {
k -= Sp[left].size + 1; now = Sp[now].ch[1];
}
else if (Sp[left].size >= k)now = left;
else return now;
}
} int build(int l, int r, int fa) {
if (l > r)return 0;
if (l == r) {
Sp[l].fa = fa; Sp[l].maxx = Sp[l].value = a[l];
Sp[l].size = 1; return l;
}
int mid = (l + r) >> 1;
Sp[mid].ch[0] = build(l, mid - 1, mid);
Sp[mid].ch[1] = build(mid + 1, r, mid);
Sp[mid].value = a[mid];
Sp[mid].fa = fa;
pushup(mid);
return mid;
} int split(int l, int r) {
l = kth(l); r = kth(r + 2);
SPLAY(l, 0); SPLAY(r, l);
return Sp[Sp[root].ch[1]].ch[0];
} void upd(int l, int r, int v) {
int now = split(l, r);
Sp[now].lazy += v; Sp[now].maxx += v; Sp[now].value += v;
pushup(Sp[root].ch[1]); pushup(root);
} void Reverse(int l, int r) {
int now = split(l, r);
Sp[now].rev ^= 1;
swap(Sp[now].ch[0], Sp[now].ch[1]);
pushup(Sp[root].ch[1]); pushup(root);
}
int query(int l, int r) {
return Sp[split(l, r)].maxx;
} void dfs(int rt) {
pushdown(rt);
if (Sp[rt].ch[0])dfs(Sp[rt].ch[0]);
if (Sp[rt].value != inf && Sp[rt].value != -inf) {
cout << Sp[rt].value << ' ';
}
if (Sp[rt].ch[1])dfs(Sp[rt].ch[1]);
} int main()
{
//ios::sync_with_stdio(0);
rdint(n); rdint(m);
for (int i = 2; i <= n + 1; i++)a[i] = i - 1;
a[1] = -inf; a[n + 2] = inf;
root = build(1, n + 2, 0);
while (m--) {
int l, r; rdint(l); rdint(r);
Reverse(l, r);
}
dfs(root); cout << endl;
return 0;
}

【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223的更多相关文章

  1. bzoj 3223 文艺平衡树 splay 区间翻转

    Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17715  Solved: 7769[Submit][Status][ ...

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

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

  3. 文艺平衡树(区间翻转)(Splay模板)

    这篇blog写的吼啊 #include<cstdio> #include<iostream> #include<cstring> using namespace s ...

  4. [bzoj3223]文艺平衡树(splay区间反转模板)

    解题关键:splay模板题. #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  5. 洛谷 3391 【模板】文艺平衡树 Treap区间翻转

    [题解] 用Treap维护这个序列. 加入的时候直接插入到末尾,这样Treap就变成一棵以插入时间先后为排序关键字的二叉搜索树. 对于翻转操作,我们分裂出需要翻转的区间,给这个区间的root打一个翻转 ...

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

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

  7. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

  8. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  9. bzoj3223: Tyvj 1729 文艺平衡树 splay裸题

    splay区间翻转即可 /************************************************************** Problem: 3223 User: walf ...

随机推荐

  1. mysql索引最左匹配原则的理解

    CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `ci ...

  2. 10-23C#基础--结构体

    结构体: 1.定义:封装小型相关变量组,里面可以放一系列的变量: 就是一个变量组,将一组变量放在一起,结构体一般定义在Main函数上面,位于Class下面,作为一个类:一般情况Struct定义在Mai ...

  3. 具有避障和寻线功能的Arduino小车

    标签:  Arduino  乐高  机器人 创客对于成年人来说,多半是科技娱乐,或者是一种是一种向往科技的人生态度,总是希望自己不仅可以看到或者听到科技的资讯,还希望能够亲身制作科技玩意,从而更好地体 ...

  4. leetcode874

    这道题直接按照题意来解,建立坐标系和移动方案,思路是比较简单的.只是需要注意需要使用set来判断是否遇到障碍,否则会超时. int robotSim(vector<int>& co ...

  5. Jsonp实现跨域请求Ajax

    客户端 #!/usr/bin/env python import tornado.ioloop import tornado.web class MainHandler(tornado.web.Req ...

  6. 列表控件JList的使用

    --------------siwuxie095                             工程名:TestUI 包名:com.siwuxie095.ui 类名:TestList.jav ...

  7. C++——static

    1.第一条也是最重要的一条:隐藏.(static函数,static变量均可) 所有未加static前缀的全局变量和函数都具有全局可见性:加static前缀的全局变量和函数只有有局部可见性: //a.c ...

  8. C语言-郝斌笔记-001求二次方程的根

    求二次方程的根 #include <stdio.h > #include<math.h> int main(void) { //把三个系数保存到计算机中 ; //=不表示相等, ...

  9. Jsp入门第二天

    1. JSP 指令: JSP指令(directive)是为JSP引擎而设计的. 它们并不直接产生任何可见输出, 而只是告诉引擎如何处理JSP页面中的其余部分. 2. 在目前的JSP 2.0中,定义了p ...

  10. (数组)对数组中的数字加1(plus one)

    题目:https://www.nowcoder.com/practice/4d135ddb2e8649ddb59ee7ac079aa882?tpId=46&tqId=29111&tPa ...