题目不说了,就是区间翻转

传送门:BZOJ 3223 和 CodeVS 3243

第一道题中是1~n的区间翻转,而第二道题对于每个1~n还有一个附加值

实际上两道题的思路是一样的,第二题把值对应到位置就行了

这里我们用伸展树来解决,但其中用到了线段树中的标记思想

对于一个长度的为n的序列,我们把它的每一位向后移动一位,即1~n → 2~n+1,然后再在序列前后分别补上一位:1和n+2。所以我们需要建立一颗节点数为n+2的伸展树,而原序列中的1~n位分别对应新序列中的2~n+1位。

对于每次询问的l和r,实际上就是l+1和r+1,首先找到l+1前一位对应的元素和r+1后一位对应的元素,即l和r+2分别对应的元素的序号。然后将l对应元素通过splay操作旋转到根节点,将r+2对应元素旋转到根节点的右儿子,由排序二叉树的性质可知,r+2的左儿子就是序列l+1~r+1,也就是询问中需要翻转的区间。对r+2的左儿子直接打上标记,在之后找元素序号的时候要记得把标记下传,同时用swap操作来达到翻转的目的。

splay操作和rotate操作在此不赘述。

最后输出的时候,同样查找2~n+1对应的元素序号,将得到的值减1还原,对于CodeVS 3243就再套一个值输出即可。

这里给出BZOJ 3223的代码。

 #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#include <string>
#include <map>
typedef long long ll;
using namespace std;
const int MAXN = ;
int n, m;
int root;
int son[MAXN][], fa[MAXN], lazy[MAXN], siz[MAXN]; inline int gi() {
char c;
int sum = , f = ;
c = getchar();
while (c < '' || c > '') {
if (c == '-')
f = -;
c = getchar();
}
while (c >= '' && c <= '') {
sum = sum * + c - '';
c = getchar();
}
return sum * f;
} void build(int l, int r, int f) {
if (l > r)
return;
if (l == r) {
siz[l] = ;
fa[l] = f;
son[f][l > f] = l;
return;
}
int mid = (l + r) >> ;
build(l, mid - , mid);
build(mid + , r, mid);
siz[mid] = siz[son[mid][]] + siz[son[mid][]] + ;
fa[mid] = f;
son[f][mid > f] = mid;
} void pushdown(int o) {
swap(son[o][], son[o][]);
lazy[son[o][]] ^= ;
lazy[son[o][]] ^= ;
lazy[o] = ;
} int find(int o, int p) {
if (lazy[o])
pushdown(o);
int l = son[o][];
int r = son[o][];
if (siz[l] + == p)
return o;
if (siz[l] >= p)
return find(l, p);
else
return find(r, p - siz[l] - );
} void rotate(int x, int &to) {
int l, r;
int f = fa[x];
int ff = fa[f];
l = son[f][] == x ? : ;
r = l ^ ;
if (f == to)
to = x;
else
son[ff][son[ff][] == f] = x;
fa[x] = fa[f];
fa[f] = x;
fa[son[x][r]] = f;
son[f][l] = son[x][r];
son[x][r] = f;
siz[f] = siz[son[f][]] + siz[son[f][]] + ;
siz[x] = siz[son[x][]] + siz[son[x][]] + ;
} void splay(int x, int &to) {
while (x != to) {
int f = fa[x];
int ff = fa[f];
if (f != to) {
if ((son[f][] == x) ^ (son[ff][] == f))
rotate(x, to);
else
rotate(f, to);
}
rotate(x, to);
}
} void reserve(int l, int r) {
int x = find(root, l);
int y = find(root, r + );
splay(x, root);
splay(y, son[x][]);
lazy[son[y][]] ^= ;
} int main() {
n = gi();
m = gi();
build(, n + , );
root = (n + ) >> ;
for (int i = ; i <= m; i++) {
int l = gi();
int r = gi();
reserve(l, r);
}
for (int i = ; i <= n + ; i++)
printf("%d ", find(root, i) - );
return ;
}

[BZOJ 3223 & Tyvj 1729]文艺平衡树 & [CodeVS 3243]区间翻转的更多相关文章

  1. BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题

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

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

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

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

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

  4. bzoj 3223: Tyvj 1729 文艺平衡树 (splay)

    链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3223 题面: 3223: Tyvj 1729 文艺平衡树 Time Limit: 10 S ...

  5. bzoj 3223/tyvj 1729 文艺平衡树 splay tree

    原题链接:http://www.tyvj.cn/p/1729 这道题以前用c语言写的splay tree水过了.. 现在接触了c++重写一遍... 只涉及区间翻转,由于没有删除操作故不带垃圾回收,具体 ...

  6. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...

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

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3223 [题目大意] 给出一数列,问m次区间翻转后的结果. [题解] Splay 区间翻 ...

  8. BZOJ - 3223 Tyvj 1729 文艺平衡树 (splay/无旋treap)

    题目链接 splay: #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f ...

  9. BZOJ 3223 Tyvj 1729 文艺平衡树 | Splay 维护序列关系

    题解: 每次reverse(l,r) 把l-1转到根,r+1变成他的右儿子,给r+1的左儿子打个标记就是一次反转操作了 每次find和dfs输出的时候下放标记,把左儿子和右儿子换一下 记得建树的时候建 ...

随机推荐

  1. 初识ReactJs(一)

    React的开发背景 ReactJS官网地址:http://facebook.github.io/react/ Github地址:https://github.com/facebook/react J ...

  2. Java开发工具安装步骤内容如下

    Java开发工具安装步骤内容如下 安装 开发工具 STS 链接下载网址 eclipse 链接下载网址 JDK安装 jdk链接下载地址 Marven环境 marven链接下载地址 Tomcat tomc ...

  3. java 字符串判断是否相等

    在其它编程语言中,判断字符串通常用"=="进行判断,但是在java中由于String类型是一个对象,不能使用"=="进行判断 需要使用equals()方法.

  4. linux 下安装PHP的IMAP扩展实现邮件收发

    系统CentOS 6.5 PHP5.5.19 1.安装imap的依赖包: [root@iZ9482lp6yqZ]# yum install -y libc-client-*  没有安装编译错误提示: ...

  5. Msbuild项目集成右键菜单编译

    DS1.背景:   我们为什么要将VS2008命令行编译.sln文件集成到右键菜单呢? 原因一:VS2008很好很强大,但太费系统资源了,尤其是在虚拟机在里面装VS2008的时候更是如此. 原因二:有 ...

  6. 多线程完成socket

    //服务器端代码 public class Service { //服务器 public static void main(String[] args) { ServerSocket serverSo ...

  7. Linux安装node

    以Ubuntu为例 1.apt-get update 2.apt-get install python gcc make g++ 3.wget https://nodejs.org/dist/v4.3 ...

  8. SQL语句导致cpu占用如此高

    一般我们可以使用sql server自带的性能分析追踪工具sql profiler分析数据库设计所产生问题的来源,进行有针对性的处理.但我们也可以通过自己写SQL语句来有针对性的进行性能方面的查询.通 ...

  9. PHP文件的读取

    1.PHP部分文件操作函数 ( fopen ,fread ,filesize,fwrite,fclose ) 2.unlink()  rmdir() 删除函数 unlink(路径和文件名): rmdi ...

  10. 移动端flex布局 微信和UC的兼容性

    请查看以下两个链接 http://www.tuicool.com/articles/Afq6Bzq http://www.sheng00.com/2148.html