准备学lct,于是重学splay。

静态splay

//Au: Hany01
//Prob: Splay
//Date: Dec 3rd, 2017
//Email: hany01@foxmail.com#include<bits/stdc++.h>using namespace std;typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;#define For(i , j , k) for (int i = (j) , i##_end_ = (k) ; i <= i##_end_ ; ++ i)
#define Fordown(i , j , k) for (int i = (j) , i##_end_ = (k) ; i >= i##_end_ ; -- i)
#define Set(a , b) memset(a , b , sizeof(a))
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define fir first
#define sec second
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#ifdef hany01
#define debug(...) fprintf(stderr , __VA_ARGS__)
#else
#define debug(...)
#endiftemplate <typename T> inline bool chkmax(T &a , T b) { return a < b ? (a = b , 1) : 0; }
template <typename T> inline bool chkmin(T &a , T b) { return b < a ? (a = b , 1) : 0; }inline int read()
{register int _ , __; register char c_;for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1;for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);return _ * __;
}inline void File()
{
#ifdef hany01freopen("splay.in" , "r" , stdin);freopen("splay.out" , "w" , stdout);
#endif
}const int maxn = 100005;int sz[maxn], va[maxn], ch[maxn][2], flag[maxn], n, m, cnt, rt;inline void maintain(int o) { sz[o] = sz[ch[o][0]] + sz[ch[o][1]] + 1; }inline void pushdown(int x) {if (flag[x]) {flag[x] = 0; swap(ch[x][0], ch[x][1]);flag[ch[x][0]] ^= 1; flag[ch[x][1]] ^= 1;}
}int build(int n)
{if (!n) return 0;int lc = build(n >> 1);int now = ++ cnt;va[now] = now - 1;ch[now][0] = lc;ch[now][1] = build(n - (n >> 1) - 1);maintain(now);return now;
}inline void Init()
{n = read(); m = read();rt = build(n + 1);
}inline int cmp(int x, int k)
{if (k == sz[ch[x][0]] + 1) return -1;return k > sz[ch[x][0]];
}inline void rotate(int &o, int d)
{int k = ch[o][d ^ 1];ch[o][d ^ 1] = ch[k][d]; ch[k][d] = o;maintain(o); maintain(k); o = k;
}void splay(int &o, int k)
{pushdown(o);register int d = cmp(o, k);if (d == -1) return ;if (d) k -= sz[ch[o][0]] + 1;int p = ch[o][d];pushdown(p);int d2 = cmp(p, k);if (d2 >= 0){int k2 = d2 ? k - sz[ch[p][0]] - 1 : k;splay(ch[p][d2], k2);if (d == d2) rotate(o, d ^ 1); else rotate(ch[o][d], d);}rotate(o, d ^ 1);
}void DEBUG(int x)
{if (!x) return ;pushdown(x);DEBUG(ch[x][0]);printf("%d ", va[x]);DEBUG(ch[x][1]);
}inline int merge(int x, int y)
{
//  cout << x << ' ' << sz[x] << endl;
//  DEBUG(x);
//  putchar('\n');splay(x, sz[x]);ch[x][1] = y;maintain(x);return x;
}inline void split(int o, int k, int &l, int &r)
{splay(o, k);l = o;r = ch[o][1];ch[l][1] = 0;maintain(l);
}inline void Solve()
{while (m --){register int l, r;l = read(); r = read();register int le, ri, md, o;split(rt, l, le, o);split(o, r - l + 1, md, ri);flag[md] ^= 1;rt = merge(merge(le, md), ri);}
}void Print(int x)
{if (!x) return ;pushdown(x);Print(ch[x][0]);if (va[x]) printf("%d ", va[x]);Print(ch[x][1]);
}int main()
{File();Init();Solve();Print(rt);return 0;
}
//夫子何为者,栖栖一代中。
//地犹鄹氏邑,宅即鲁王宫。
//叹凤嗟身否,伤麟怨道穷。
//今看两楹奠,当与梦时同。
//--唐玄宗《经邹鲁祭孔子而叹之》

动态splay

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define For(i , j , k) for (int i = (int)(j) ; i <= (int)(k) ; ++ i)
#define Fordown(i , j , k) for (int i = (int)(j) ; i >= (int)(k) ; -- i)
#define Set(a , b) memset(a , b , sizeof(a))
using namespace std;const int maxn = 100010;
struct node
{node *ch[2];int num , s , flag;node(){s = flag = num = 0;}
}*rt , *null;
int n , m , nn , l , r , ans[maxn] , anss;inline int cmp(node *o , int k)
{int d = k - o->ch[0]->s;if (d == 1)return -1;return d <= 0 ? 0 : 1;
}inline void maintain(node* &o)
{o -> s = 1 + o -> ch[0] -> s + o -> ch[1] -> s;
}inline void pushdown(node* &o)
{if (o -> flag){o -> flag = 0;swap(o -> ch[0] , o -> ch[1]);o -> ch[0] -> flag ^= 1;o -> ch[1] -> flag ^= 1;}
}node* build(int k)
{if (!k)return null;node *o = new node;o -> ch[0] = build(k / 2);o -> num = ++ n;o -> ch[1] = build(k - k / 2 - 1);o -> flag = o -> s = 0;maintain(o);return o;
}void Init()
{scanf("%d%d" , &nn , &m);null = new node;n = 0;rt = build(nn + 1);
}void rotate(node* &o , int d)
{node *k;k = o -> ch[d ^ 1];o -> ch[d ^ 1] = k -> ch[d];k -> ch[d] = o;maintain(o);maintain(k);o = k;
}void splay(node* &o , int k)
{pushdown(o);int d = cmp(o , k);if (d == 1)k -= o->ch[0]->s + 1;if (d >= 0){node *p = o -> ch[d];pushdown(p);int d2 = cmp(p , k);int k2 = k;if (d2)k2 -= p->ch[0]->s + 1;if (d2 != -1){splay(p->ch[d2] , k2);if (d == d2)rotate(o , d ^ 1);elserotate(o->ch[d] , d);}rotate(o , d ^ 1);}
}node* merge(node* l , node* r)
{splay(l , l -> s);l -> ch[1] = r;maintain(l);return l;
}void split(node* rt , int k , node* &l , node* &r)
{splay(rt , k);l = rt;r = rt -> ch[1];rt -> ch[1] = null;maintain(l);
}void Solve()
{while (m --){scanf("%d%d" , &l , &r);node *le , *ri , *mi , *o;split(rt , l , le , o);split(o , r - l + 1 , mi , ri);mi -> flag ^= 1;rt = merge(merge(le , mi) , ri);}
}void Print(node *u)
{if (u == null)return ;pushdown(u);Print(u -> ch[0]);ans[anss ++] = u -> num;Print(u -> ch[1]);
}int main()
{
#ifndef ONLINE_JUDGEfreopen("Splay.in" , "r" , stdin);freopen("Splay1.out" , "w" , stdout);
#endifInit();Solve();Print(rt);For(i , 1 , anss - 1)printf("%d " , ans[i] - 1);return 0;
}
//风吹柳花满店香,吴姬压酒唤客尝。
//金陵子弟来相送,欲行不行各尽觞。
//请君试问东流水,别意与之谁短长。
//--李白《金陵酒肆留别》

另一种简洁的旋转操作(保存父节点)

inline void rotate(int x)
{int f = fa[x], gf = fa[f], d = dir(x), gd = dir(f);//The followed 2 lines can't be reversed!!//Because if you reverse them, the second line will change the value of ch[x][d^1];fa[ch[f][d] = ch[x][d ^ 1]] = f;//!ch[fa[f] = x][d ^ 1] = f;//!fa[ch[gf][gd] = x] = gf;maintain(f); maintain(x);
}

【BZOJ 3223】 文艺平衡树 (splay 板子)相关推荐

  1. BZOJ 3223 文艺平衡树

    BZOJ 3223 文艺平衡树 题意 一个 1~n 的序列,有m次询问,每次询问翻转其中的一个区间.输出最后的区间. 题解 这是一棵加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. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

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

  4. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  5. 文艺平衡树 Splay 学习笔记(1)

    (这里是Splay基础操作,reserve什么的会在下一篇里面讲) 好久之前就说要学Splay了,结果苟到现在才学习. 可能是最近良心发现自己实在太弱了,听数学又听不懂只好多学点不要脑子的数据结构. ...

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

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

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

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

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

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

  9. 文艺平衡树(Splay)

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

  10. [Tyvj 1729] 文艺平衡树

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

最新文章

  1. 军事科学院医学研究院认知与脑科学研究团队2021年诚聘启事(更新)
  2. 用Word写博客园文章
  3. leetcode--数组(Easy)
  4. mac怎么查看gitlab的注册邮箱_163电子邮箱怎么注册申请?手机号注册电子邮箱的小技巧...
  5. ASA virtual telnet
  6. Visio(流程图绘制软件)的免费替代品
  7. 杭电OJ 1720 进制处理
  8. 《LaTeX入门》刘海洋的杂谈勾股定理的完整源码
  9. 对称、群论与魔术(五)——真实扑克牌图案的对称性探索
  10. java pdf 背景图,Java 设置PDF文档背景——单色背景、图片背景
  11. js 26个字母排序
  12. 【V2ray 报错 failed to read response header】
  13. PLC信号处理系列之开关量信号(DI)防抖
  14. 网易云音乐用户微观洞察精细化运营
  15. java图形界面编程 房子_Java图形界面编程
  16. SAP上线时未清采购订单处理
  17. Markdown语法之html内嵌样式
  18. %llu 64位无符号%d、%u、%x/%X、%o%f、%e/%E或%g/%G
  19. 把MySQL语句转换为sqlserver_mysql语句转换为sql server语句
  20. 微信小程序之列表加载

热门文章

  1. PHP7.0至PHP8部分特性总结
  2. helpdesk软件维护异常处理方法,提供工作效率
  3. androidx.recyclerview:recyclerview的使用
  4. Form表单提交与Validform验证的那些事
  5. Simulink小问题集锦
  6. python RSA非对称加解密模块[M2Crypto]
  7. tomcat首页welcome-file-list设置与url-pattern匹配规则
  8. html 字号和像素的关系,像素与分辨率的关系
  9. window下创建软连接
  10. 2018年东北农业大学春季校赛 题解