【BZOJ 3223】 文艺平衡树 (splay 板子)
来源:互联网 发布:植物生长算法 编辑:程序博客网 时间:2024/05/20 11:21
准备学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 hany01 freopen("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); else rotate(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_JUDGE freopen("Splay.in" , "r" , stdin); freopen("Splay1.out" , "w" , stdout);#endif Init(); 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);}
阅读全文
1 0
- 【BZOJ 3223】 文艺平衡树 (splay 板子)
- BZOJ 3223 文艺平衡树 (splay)
- 【Splay】bzoj 3223 文艺平衡树
- BZOJ 3223 文艺平衡树 【Splay】
- 【splay】BZOJ 3223 文艺平衡树
- bzoj 3223 文艺平衡树 Splay
- [BZOJ 3223]Tyvj 1729 文艺平衡树(Splay)
- 区间翻转 bzoj 3223 文艺平衡树 (splay)
- [SPLAY维护区间][BZOJ 3223][TYVJ 1729]文艺平衡树
- [省选前衡八题目整理][BZOJ 3223]文艺平衡树(Splay)
- bzoj 3223/tyvj 1729 文艺平衡树 splay tree
- bzoj 3223 Tyvj 1729 文艺平衡树 Splay
- bzoj 3223 Tyvj 1729 文艺平衡树 [Splay]
- Bzoj 3223: Tyvj 1729 文艺平衡树(splay)
- BZOJ 3223: Tyvj 1729 文艺平衡树 splay
- bzoj 3223 文艺平衡树 Splay详细解析
- 【BZOJ】Tyvj 1729 文艺平衡树 Splay
- bzoj 3223: Tyvj 1729 文艺平衡树(splay 模板题 区间翻转)
- 运行shipyard镜像出现Unauthorized request
- IDEA新建MAVEN项目时速度缓慢
- dede验证码只显示背景不显示图片解决方法
- 关于Android中的BInder机制的笔记
- 基础练习 回文数
- 【BZOJ 3223】 文艺平衡树 (splay 板子)
- 矩阵连乘问题
- caffe之python接口实战 :mnist_siamese 官方教程源码解析
- Cash Loan(一):Redis实现计数器---接口防刷
- Fragment详解
- (转)JS日期转换为指定格式字符串
- Python数据抓取(1) —数据处理前的准备
- Linux中内部命令和外部命令
- 第一篇博客