BZOJ3223: Tyvj 1729 文艺平衡树(Splay) (指针版+数组版)
2015-11-22 16:43
453 查看
传送门
Splay的区间翻转:若要翻转[l, r],将l-1 Splay到根,将r+1 Splay到l-1的右儿子,然后[l, r]就在r+1的左儿子的位置了,给它打上标记,完工!
哦,写的时候一定要注意随时pushdown,以免出错.
数组版
指针版
Splay的区间翻转:若要翻转[l, r],将l-1 Splay到根,将r+1 Splay到l-1的右儿子,然后[l, r]就在r+1的左儿子的位置了,给它打上标记,完工!
哦,写的时候一定要注意随时pushdown,以免出错.
数组版
/************************************************************** Problem: 3223 User: geng4512 Language: C++ Result: Accepted Time:1868 ms Memory:4712 kb ****************************************************************/ #include<cstdio> #define MAXN 200005 int tmp; inline void Swap(int &a, int &b) { tmp = a; a = b; b = tmp; } struct node { int sz, ch[2], f; bool rev; inline void mt() { Swap(ch[0], ch[1]); } }t[MAXN]; int rt, sz, n, m; #define Upd(r) {t[r].sz = t[t[r].ch[0]].sz + t[t[r].ch[1]].sz + 1;} void rot(int x) { int y = t[x].f, z = t[y].f; bool f = (t[y].ch[1] == x); t[y].ch[f] = t[x].ch[f^1]; if(t[y].ch[f]) t[t[y].ch[f]].f = y; t[x].ch[f^1] = y; t[y].f = x; t[x].f = z; if(z) t[z].ch[t[z].ch[1]==y] = x; Upd(y); } inline void pushdown(int y) { if(t[y].rev) {t[y].mt(); t[t[y].ch[0]].rev ^= 1; t[t[y].ch[1]].rev ^= 1; t[y].rev = 0;} } void Splay(int r, int tp) { for(int y, z; (y = t[r].f) != tp; rot(r)) { pushdown(r); z = t[y].f; if(z == tp) continue; if( (t[z].ch[0] == y) == (t[y].ch[0] == r) ) rot(y); else rot(r); } if(!tp) rt = r; Upd(r); } int Kth(int x) { int y=rt,p; if(x>t[rt].sz)return 0; while(1) { pushdown(y); p=t[y].ch[0]; if(t[p].sz+1<x) { x-=t[p].sz+1; y=t[y].ch[1]; } else if(t[p].sz>=x) y=p; else return y; } } int Build(int l, int r) { if(l > r) return 0; int mid = (l + r) >> 1; t[mid].ch[0] = Build(l, mid-1); t[mid].ch[1] = Build(mid+1, r); Upd(mid); t[t[mid].ch[0]].f = t[t[mid].ch[1]].f = mid; return mid; } void Rev(int l, int r) { int a = Kth(l), b = Kth(r+2); Splay(a, 0); Splay(b, a); int p = t[b].ch[0]; t[p].rev ^= 1; } void print(int x) { if(x == 0) return; pushdown(x); print(t[x].ch[0]); if(x != 1 && x != n + 2) printf("%d ", x-1); print(t[x].ch[1]); } char c, f; inline void GET(int &n) { n = 0; f = 1; do {c = getchar(); if(c == '-') f = -1;} while(c > '9' || c < '0'); while(c >= '0' && c <= '9') {n=n*10+c-'0';c=getchar();} n *= f; } int main() { int l, r; GET(n); GET(m); rt = Build(1, n+2); while(m --) { GET(l); GET(r); Rev(l, r); } print(rt); }
指针版
/************************************************************** Problem: 3223 User: geng4512 Language: C++ Result: Accepted Time:1912 ms Memory:5492 kb ****************************************************************/ #include<cstdio> #define MAXN 200005 struct Node { int sz, v; bool rev; Node *ch[2], *fa; inline void sw() {Node *tmp = ch[0]; ch[0] = ch[1]; ch[1] = tmp; rev ^=1; } }t[MAXN], NIL, *nil = &NIL, *rt; int n, m; inline void Upd(Node *p) { p->sz = p->ch[0]->sz + p->ch[1]->sz + 1; } inline void pushdown(Node *p) { if(p->rev) { p->rev = 0; if(p->ch[0] != nil) p->ch[0]->sw(); if(p->ch[1] != nil) p->ch[1]->sw(); } } Node *Build(int l, int r, Node*fa = nil) { if(l > r) return nil; int mid = (l + r) >> 1; t[mid].v = mid; t[mid].ch[0] = Build(l, mid-1, &t[mid]); t[mid].ch[1] = Build(mid+1, r, &t[mid]); t[mid].fa = fa; Upd(&t[mid]); return &t[mid]; } void Rot(Node *x) { Node *y = x->fa, *z = y->fa; bool f = (y->ch[1] == x); pushdown(y); pushdown(x); y->ch[f] = x->ch[f^1]; if(y->ch[f] != nil) y->ch[f]->fa = y; x->ch[f^1] = y; y->fa = x; x->fa = z; if(z != nil) z->ch[z->ch[1]==y] = x; Upd(y); } char c, f; inline void GET(int &n) { n = 0; f = 1; do {c = getchar(); if(c == '-') f = -1;} while(c > '9' || c < '0'); while(c >= '0' && c <= '9') {n=n*10+c-'0';c=getchar();} n *= f; } void Splay(Node *x, Node *to, Node *&Root = rt) { for(Node *y, *z; (y = x->fa) != to; Rot(x)) { z = y->fa; if(z == to) continue; if((z->ch[1] == y) == (y->ch[1] == x)) Rot(y); else Rot(x); } if(to == nil) Root = x; Upd(x); } Node *Kth(int k, Node *to = nil, Node *&Root = rt) { Node *y = Root, *z; if(y->sz < k) return nil; while(1) { pushdown(y); z = y->ch[0]; if(z->sz + 1 < k) { k -= z->sz + 1; y = y->ch[1]; } else if(z->sz >= k) y = y->ch[0]; else break; } Splay(y, to, Root); return y; } inline void Rev(int l, int r) { Node *a = Kth(l), *b = Kth(r+2, a); b->ch[0]->sw(); } void print(Node *p) { pushdown(p); if(p->ch[0] != nil) print(p->ch[0]); if(p->v != 1 && p->v != n+2) printf("%d ", p->v-1); if(p->ch[1] != nil) print(p->ch[1]); } int main() { //freopen("C:\\1.txt", "r", stdin); int l, r; GET(n); GET(m); rt = Build(1, n+2); while(m --) { GET(l); GET(r); Rev(l, r); } print(rt); }
相关文章推荐
- Wireshark教程
- 函数buf_pool_init_instance
- servlet中实现页面跳转
- 动态设置RelativeLayout布局
- svn中的revert和update
- XCode中类似reveal功能
- 剑指Offer-29-查找数组中出现次数超过一般的元素
- UIBezierPath的自定义路径绘图
- Extjs MVC开发模式详解
- Linux top命令
- Python制作简单的网页爬虫
- 函数outer()
- HDU1219-AC Me
- 二叉树的先序,中序,后序遍历
- VS和Liux环境下分别编译boost标准库
- 使用Chrome调试JavaScript的断点设置和调试技巧
- Layout.xml中控件的ID命名方式
- 《软件需求模式》阅读笔记之四
- [LeetCode]Binary Tree Preorder Traversal
- 函数buf_pool_init