uva 11922 Permutation Transformer(Splay tree,懒标记传递)
来源:互联网 发布:淘宝网上开店实战入门 编辑:程序博客网 时间:2024/04/28 20:40
wiki
http://zh.wikipedia.org/wiki/%E4%BC%B8%E5%B1%95%E6%A0%91
关于Splay tree效率分析(包括三种旋转方式图解):
http://www.cs.waikato.ac.nz/Teaching/COMP317B/Week_6/Splay_tree.html
注意,Splay tree的三种旋转中,x的父节点不是root且三点不同线的情况,是在祖父节点做两次同样的旋转。
取出一段区间放到末尾,直接用splay tree可以完成。要做翻转则用到lazy mark。预处理要先加一个虚拟节点,否则a=1时,不满足split的参数要求。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>#include <queue>#include <stack>#include <cassert>#include <algorithm>#include <cmath>#include <set>#include <limits>using namespace std;#define MIN(a, b) ((a) < (b) ? (a) : (b))#define MAX(a, b) ((a) > (b) ? (a) : (b))#define REP(i, s, t) for(int (i)=(s);(i)<=(t);++(i))#define UREP(i, s, t) for(int (i)=(s);(i)>=(t);--(i))#define REPOK(i, s, t, o) for(int (i)=(s);(i)<=(t) && (o);++(i))#define MAXN 100#define MAXM 10000#define MOD 10000007#define PI 3.1415926535897932384626433832795#define HALF_PI 1.5707963267948966192313216916398typedef long long LL;const double maxdouble = numeric_limits<double>::max();const double eps = 1e-10;const int INF = 0x7FFFFFFF;// Splay Tree 伸展树// 把一棵Splay tree看作一段区间 其中每一棵子树都是一段小区间// 不一定要满足BST的性质 可以维护一种顺序关系 例如让某段区间翻转// 可以加上lazy marktypedef struct Node { Node *ch[2]; int v; // value int s; // size 名次树中子树结点个数 int flip; int cmp(int k) const { int d = k - ch[0]->s; if (d == 1) return -1; return d <= 0 ? 0 : 1; } void maintain() { s = ch[0]->s+ch[1]->s+1; } void pushdown() { if (flip) { flip = 0; swap(ch[0], ch[1]); ch[0]->flip = !ch[0]->flip; ch[1]->flip = !ch[1]->flip; } }}SplayTreeNode;const int maxnode = 100000 + 10;SplayTreeNode nullSpace; // null指向的内存SplayTreeNode* null = &nullSpace;struct SplayTree { int n; // seq 是预先分配的储存节点的空间 这样不用动态申请 SplayTreeNode seq[maxnode+5]; SplayTreeNode* root; void rotate(SplayTreeNode* &o, int d) { SplayTreeNode* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; o->maintain(); k->maintain(); o = k; } void splay(SplayTreeNode* &o, int k) { o->pushdown(); int d = o->cmp(k); if (d == 1) k -= o->ch[0]->s + 1; if (d != -1) { SplayTreeNode* p = o->ch[d]; p->pushdown(); int d2 = p->cmp(k); int k2 = d2 == 0 ? k : k - 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); } } // 合并两棵splay tree // 先将第一棵树的最大节点伸展 结果是根节点没有右子树 // left不能为null SplayTreeNode* merge(SplayTreeNode* &left, SplayTreeNode* &right) { splay(left, left->s); left->ch[1] = right; left->maintain(); return left; } // 把o的前k小结点放在left里,其他的放在right里。 // !!!1<=k<=o->s。当k=o->s时,right=null void split(SplayTreeNode* o, int k, SplayTreeNode* &left, SplayTreeNode* &right) { splay(o, k); left = o; right = o->ch[1]; if (o->ch[1] != null) o->ch[1] = null; left->maintain(); } Node* build(int sz) { if (!sz) return null; Node* L = build(sz/2); Node* o = &seq[++n]; o->v = n; o->ch[0] = L; o->ch[1] = build(sz - sz/2 - 1); o->flip = o->s = 0; o->maintain(); return o; } void init(int sz) { n = 0; null->s = 0; root = build(sz); }};SplayTree tree;void print(SplayTreeNode* o) { if (o->flip) o->pushdown(); if (o->ch[0] != null) print(o->ch[0]); if (o->v != 1) printf("%d\n",o->v-1); if (o->ch[1] != null) print(o->ch[1]);}void debug(SplayTreeNode *x) { printf("\n---debug----\n"); print(x); printf("---debug----\n");}int main() { freopen("input.in", "r", stdin); int n, m; scanf("%d%d",&n,&m); tree.init(n+1); //debug(); int a, b; SplayTreeNode *first, *second, *third; REP(i, 1, m) { scanf("%d%d",&a,&b); tree.split(tree.root, a, first, second); tree.split(second, b - a + 1, second, third); second->flip = !second->flip; if (third != null) { tree.merge(third, second); tree.merge(first, third); } else { tree.merge(first, second); } //debug(third); tree.root = first; //debug(tree.root); } print(tree.root); return 0;}
0 0
- uva 11922 Permutation Transformer(Splay tree,懒标记传递)
- 【splay tree】 UVA 11922 Permutation Transformer
- UVA 11922 Permutation Transformer(Splay Tree)
- UVA 11922 Permutation Transformer Splay
- UVA 11922 Permutation Transformer(splay)
- UVa 11922 Permutation Transformer(splay)
- UVA 11922 Permutation Transformer(伸展树 Splay Tree)
- UVa 11922 - Permutation Transformer (Splay)
- UVA 11922 Permutation Transformer(splay树)
- Permutation Transformer+uva+splay树
- UVA 11922 Permutation Transformer Splay 区间翻转 + 区间合并
- UVA 11922 Permutation Transformer (Splay 区间翻转 + 复制粘贴)
- uva 11922 - Permutation Transformer
- uva 11922 Permutation Transformer
- uva 11922 Permutation Transforme/splay tree
- 11922 - Permutation Transformer (Splay区间翻转)
- UVA11922 Permutation Transformer(Splay)
- UVA 11922 Permutation Transformer [Spaly]
- 高精度加法
- 线段树(带删除节点)
- hdu 5007 水 字符串
- 编程常见错误
- LeetCode_Search in Rotated Sorted Array
- uva 11922 Permutation Transformer(Splay tree,懒标记传递)
- UVA 11212 IDA*
- acdream 1415 最短路+边联通求桥
- 计算最小生成树
- 浅析NSNetService和NSNetServiceBrowser
- Fragment中存放GridView,结合LruCache、DiskLruCache和HttpURLConnection实现图片下载、缓存
- uva-131 - The Psychic Poker Player
- Android学习之surface学习(一)
- *t++与(*t)++差距与用法