BZOJ 3223 文艺平衡树

题意

一个 1~n 的序列,有m次询问,每次询问翻转其中的一个区间。输出最后的区间。

题解

这是一棵加lazy的平衡树……

首先,翻转区间可以通过区间内所有节点的左右儿子实现。显然我们不能暴力处理所有的点,所以我们要打lazy标记。

既然要打lazy,首先要区间内所有节点都在一棵子树里面:设区间为 [l, r],把序列中第 l - 1 个节点旋转到根节点,然后把第 r + 1 个节点旋转到根节点下面(显然这个节点会是根节点的右儿子),此时整个 [l, r] 区间中的节点都在第 r + 1 个节点的左子树中了。然后把这个子树的根节点打上lazy标记即可。

什么时候下放呢?Find的时候,每访问到一个节点都要下放;而旋转的时候,涉及到的节点在find时都已经下放完毕了,所以不用考虑下放的事情。还有就是最后输出的时候别忘了下放。

自己犯过的错误:

  1. which(u) ? xxx, xxx : xxx, xxx; 冒号左右的式子都要打括号;
  2. 这里的 Find 函数找的是“序列中的第x个点”,不是值第x大的点。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){char c;bool op = 0;while(c = getchar(), c < '0' || c > '9')if(c == '-') op = 1;x = c - '0';while(c = getchar(), c >= '0' && c <= '9')x = x * 10 + c - '0';if(op) x = -x;
}
template <class T>
void write(T x){if(x < 0) putchar('-'), x = -x;if(x >= 10) write(x / 10);putchar('0' + x % 10);
}const int N = 100005;
int n, m;
int root = 1, idx, id[N] = {-1}, sze[N], ls[N], rs[N], fa[N], lazy[N];
#define which(x) (ls[fa[(x)]] == (x))void upt(int u){sze[u] = sze[ls[u]] + sze[rs[u]] + 1;
}
void rotate(int u){int v = fa[u], w = fa[v], b = which(u) ? rs[u] : ls[u];if(w) which(v) ? ls[w] = u : rs[w] = u;which(u) ? (ls[v] = b, rs[u] = v) : (rs[v] = b, ls[u] = v);if(b) fa[b] = v;fa[v] = u, fa[u] = w;upt(v), upt(u);
}
void splay(int u, int tar){while(fa[u] != tar){if(fa[fa[u]] != tar){if(which(u) == which(fa[u])) rotate(fa[u]);else rotate(u);}rotate(u);}if(!tar) root = u;
}
void swap_son(int u){if(!u) return;lazy[u] ^= 1;swap(ls[u], rs[u]);upt(u);
}
void pushdown(int u){if(!lazy[u]) return;swap_son(ls[u]), swap_son(rs[u]);lazy[u] = 0;
}
int find(int x){int u = root;pushdown(u);while(sze[ls[u]] != x && u){if(sze[ls[u]] >= x + 1) u = ls[u];else x -= sze[ls[u]] + 1, u = rs[u];pushdown(u);}return u;
}
void reverse(int l, int r){splay(find(l - 1), 0);splay(find(r + 1), root);swap_son(ls[rs[root]]);
}
int build(int l, int r){int mid = (l + r) >> 1, u = ++idx;id[u] = mid;if(mid > l) ls[u] = build(l, mid - 1), fa[ls[u]] = u;if(mid < r) rs[u] = build(mid + 1, r), fa[rs[u]] = u;upt(u);return u;
}
void out(int u){pushdown(u);if(ls[u]) out(ls[u]);if(id[u] && id[u] <= n) write(id[u]), space;if(rs[u]) out(rs[u]);
}int main(){read(n), read(m);build(0, n + 1);while(m--){int l, r;read(l), read(r);reverse(l, r);}out(root), enter;return 0;
}

转载于:https://www.cnblogs.com/RabbitHu/p/BZOJ3223.html

BZOJ 3223 文艺平衡树相关推荐

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

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

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

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

  3. splay区间翻转(bzoj 3223: Tyvj 1729 文艺平衡树)

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 4854  Solved: 2844 [Submit][S ...

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

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

  5. [Tyvj 1729] 文艺平衡树

    题面如下: Tyvj 1729 文艺平衡树 Time Limit: 1 Sec  Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个有 ...

  6. 洛谷 P3391 【模板】文艺平衡树

    题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4 ...

  7. P5055 【模板】可持久化文艺平衡树

    P5055 [模板]可持久化文艺平衡树 突然发现fhq_treap也是可以支持区间翻转的,所以基本上和其他平衡树是一样的,而且还满足重量平衡树的性质,真是太优秀了,只不过常数稍微比较大. 然后这里我们 ...

  8. 【Splay】文艺平衡树(金牌导航 Splay-2)

    #文艺平衡树 金牌导航 Splay-2 题目大意 给你一个1~n的序列,然后对序列的区间做若干次翻转,问你最后的序列 输入样例 5 3 1 3 1 3 1 4 输出样例 4 3 2 1 5 数据范围 ...

  9. BZOJ3223文艺平衡树——非旋转treap

    此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...

最新文章

  1. PHP更新数据库记录
  2. TCPDUMP详解(续)
  3. kibana操作elasticsearch:词条匹配(term)
  4. 镀铬亮条怎么修复_老车修复:翻新小改一辆破烂不堪的经典MINI,完美大变样...
  5. 先定个小目标, 使用C# 开发的千万级应用
  6. python同步应用:多个线程有序执行
  7. pcl如何设置colorbar_突然加更 | 子图、colorbar和标题
  8. zipkin brave mysql_Zipkin和Brave实现http服务调用的跟踪
  9. 如何查看一个组件的 classid是多少_如何快速查看胎压?胎压多少才正常?带您全面了解爱车的轮胎...
  10. 设计模式之strategy模式(C++实现)
  11. 5.产品的三种流程图,你都知道吗?
  12. Soft Bellman Equation and Soft Value Iteration证明
  13. 冰点下载器手机版apk_冰点下载器手机版apk
  14. Playwright-python 教程
  15. 1006 换个格式输出整数
  16. 设计模式之多用组合,少用继承
  17. ibm服务器进去阵列卡状态,IBM阵列卡介绍和服务器对阵列卡的支持情况
  18. 深度学习实战06-循环神经网络(RNN)实现股票预测
  19. java,jbutton
  20. 华为魔术magic2拆机图_荣耀Magic2拆解:蝶式五轨滑屏 + 前后六摄

热门文章

  1. SSL Medium Strength Cipher Suites Supported (SWEET32) 支持SSL中等强度密码套件(SWEET32)中危漏洞
  2. 使用纯Java实现一个WebSSH项目
  3. 第19课 编排节目顺序
  4. PAT L1-020 帅到没朋友
  5. 大湖熊简介计算机考试,求五大湖资料
  6. 弘辽科技:什么样的淘宝店铺名字能够吸引人?技巧是什么?
  7. Java——编写一个程序模拟家族成员的姓名,姓名由姓氏和名字组成,编写一个FamilyPerson类,该类有一个静态String型成员变量surname(即姓氏)
  8. css多余文字显示三个点显示
  9. VUE - Apache 部署 Vue SPA 项目,刷新 404 , Apache 配置处理
  10. 05 高性能网络设计专栏-网络原理