[BZOJ3223]Tyvj 1729 文艺平衡树

试题描述

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

输入

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

输出

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

输入示例


输出示例

     

数据规模及约定

N,M<=100000

题解

裸 splay,注意最后要多输出一个空格。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 100010
struct Node {
int v, siz; bool rev;
Node() {}
Node(int _): v(_), rev(0) {}
} ns[maxn];
int rt, ToT, fa[maxn], ch[2][maxn];
void maintain(int o) {
ns[o].siz = 1;
for(int i = 0; i < 2; i++) if(ch[i][o])
ns[o].siz += ns[ch[i][o]].siz;
return ;
}
void build(int& o, int l, int r) {
if(l > r) return ;
int mid = l + r >> 1;
ns[o = ++ToT] = Node(mid);
if(l == r) return maintain(o);
build(ch[0][o], l, mid - 1); build(ch[1][o], mid + 1, r);
if(ch[0][o]) fa[ch[0][o]] = o;
if(ch[1][o]) fa[ch[1][o]] = o;
return maintain(o);
}
void pushdown(int o) {
for(int i = 0; i < 2; i++) if(ch[i][o])
ns[ch[i][o]].rev ^= ns[o].rev;
if(ns[o].rev) swap(ch[0][o], ch[1][o]), ns[o].rev = 0;
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[ch[1][z]==y][z] = u;
if(ch[1][y] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[r][u]] = y;
ch[l][y] = ch[r][u]; ch[r][u] = y;
maintain(y); maintain(u);
return ;
}
int S[maxn], top;
void splay(int u) {
int t = u; S[++top] = t;
while(fa[t]) t = fa[t], S[++top] = t;
while(top) pushdown(S[top--]);
while(fa[u]) {
int y = fa[u], z = fa[y];
if(z) {
if(ch[0][y] == u ^ ch[0][z] == y) rotate(u);
else rotate(y);
}
rotate(u);
}
return ;
}
int split(int u) {
if(!u) return 0;
splay(u);
int tmp = ch[1][u];
fa[tmp] = 0; ch[1][u] = 0;
maintain(u);
return tmp;
}
int merge(int a, int b) {
if(!a) return maintain(b), b;
if(!b) return maintain(a), a;
pushdown(a); while(ch[1][a]) a = ch[1][a], pushdown(a);
splay(a);
ch[1][a] = b; fa[b] = a;
return maintain(a), a;
}
int qkth(int o, int k) {
if(!o) return 0;
pushdown(o);
int ls = ch[0][o] ? ns[ch[0][o]].siz : 0;
if(k == ls + 1) return o;
if(k > ls + 1) return qkth(ch[1][o], k - ls - 1);
return qkth(ch[0][o], k);
}
int Find(int k) {
rt = 1; while(fa[rt]) rt = fa[rt];
return qkth(rt, k);
}
void Rev(int ql, int qr) {
int lrt = Find(ql - 1), mrt = Find(qr), rrt;
split(lrt); rrt = split(mrt);
ns[mrt].rev ^= 1;
mrt = merge(lrt, mrt); merge(mrt, rrt);
return ;
} int main() {
int n = read(), q = read(); build(rt, 1, n);
while(q--) {
int l = read(), r = read();
Rev(l, r);
} for(int i = 1; i <= n; i++) {
int k = Find(i);
printf("%d ", ns[k].v);
} return 0;
}

[BZOJ3223]Tyvj 1729 文艺平衡树的更多相关文章

  1. BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Sta ...

  2. bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2202  Solved: 1226[Submit][Sta ...

  3. 2018.08.05 bzoj3223: Tyvj 1729 文艺平衡树(非旋treap)

    传送门 经典的平衡树问题,之前已经用splay写过一次了,今天我突发奇想,写了一发非旋treap的版本,发现挺好写的(虽然跑不过splay). 代码: #include<bits/stdc++. ...

  4. BZOJ3223——Tyvj 1729 文艺平衡树

    1.题目大意:维护序列,只有区间翻转这个操作 2.分析:splay的经典操作就是实现区间翻转,就是在splay中有一个标记,表示这个区间被翻转了 然后就是记得各种的操作访问某个点时,记得下传,顺便交换 ...

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

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

  6. 【Splay】bzoj3223 Tyvj 1729 文艺平衡树

    #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #i ...

  7. BZOJ3223: Tyvj 1729 文艺平衡树 无旋Treap

    一开始光知道pushdown却忘了pushup......... #include<cstdio> #include<iostream> #include<cstring ...

  8. 【Splay】【块状链表】bzoj3223 Tyvj 1729 文艺平衡树

    让蒟蒻见识到了常数大+滥用STL的危害. <法一>很久之前的Splay #include<cstdio> #include<algorithm> using nam ...

  9. BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3628  Solved: 2052[Submit][Sta ...

随机推荐

  1. ubuntu源笔记

    比如说清华大学的ipv6镜像源:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ /etc/apt/sources.list为包管理工具apt的软件包 ...

  2. [LeetCode] House Robber III 打家劫舍之三

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  3. [LeetCode] Flatten 2D Vector 压平二维向量

    Implement an iterator to flatten a 2d vector. For example,Given 2d vector = [ [1,2], [3], [4,5,6] ] ...

  4. [LeetCode] Merge Intervals 合并区间

    Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8, ...

  5. C# 动态修改Config

    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); confi ...

  6. CentOS安装Redis详细教程

    构建 Redis redis 目前没有官方 RPM 安装包,我们需要从源代码编译,而为了要编译就需要安装 Make 和 GCC. 如果没有安装过 GCC 和 Make,那么就使用 yum 安装. yu ...

  7. linux 常见命令

    redhat 1.获取apt软件列表 sudo apt-cache search all 2.添加用户并创建目录 sudo useradd -m username -s /sbin/bash 3.vs ...

  8. C++ namespace

    namespace, 命名空间, 用于解决命名冲突的问题. Python中的package/module, Javascript中的object, Java中的package都具有这样的功能. 如何使 ...

  9. C阅读与学习

    征服C指针 C语言接口与实现:创建可重用软件的技术

  10. volatile修饰符

    Volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值.而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存.这样在任何时刻,两个不同的线程总是看到某个成 ...