uva 11922 Permutation Transformer
来源:互联网 发布:色环电阻计算器软件 编辑:程序博客网 时间:2024/04/28 08:06
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=229&page=show_problem&problem=3073
题目描述:给你一个1~n的序列,有m个操作,每次操作就是将下标[a ,b]区间的序列反转并且将其整体删除,然后添加到序列尾部
解题思路:这个是刘汝佳白书上的原题,主要使用伸展树(splay)维护整个区间被反转的次数。
这也是我第一次写splay ,写得过程中出了好多错误。splay就是一棵平衡的二叉树,虽然单次操作复杂度可能会很大,但是可以证明均摊复杂度是O(logn),好神奇。。。
如果已经学过AVL树,那就很简单了,splay的操作和AVL操作很类似,但是编程实现比较简单,而且有好多小技巧,建议大家自己独立写一遍
//#pragma comment(linker,"/STACK:102400000,102400000")#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<string>#define ll long long#define db double#define PB push_back#define lson k<<1#define rson k<<1|1using namespace std;const int N = 100005;struct node{ node *ch[2]; int v, s; bool flip; int cmp(int x) const { int d = x - ch[0]->s; if(d == 1) return -1; return d <= 0 ? 0 : 1; } void maintain() { s = 1 + ch[0]->s + ch[1]->s; } void pushdown() { if(flip) { flip = false; swap(ch[0], ch[1]); ch[0]->flip = !ch[0]->flip; ch[1]->flip = !ch[1]->flip; } }};void rotate(node* &o, int d){ node* k = o->ch[d ^ 1]; o->ch[d ^ 1] = k->ch[d], k->ch[d] = o; o->maintain(), k->maintain(); o = k;}node* root;node* null = new node();void splay(node* &o, int k){ o->pushdown(); int d = o->cmp(k); if(d != -1) { if(d == 1) k -= o->ch[0]->s + 1; node* p = o->ch[d]; p->pushdown(); int d2 = p->cmp(k); if(d2 != -1) { if(d2==1) k-=p->ch[0]->s+1; splay(p->ch[d2], k); if(d == d2) rotate(o, d ^ 1); else rotate(o->ch[d], d); } rotate(o, d ^ 1); }}node* merge(node* left, node* right){ splay(left, left->s); left->ch[1] = right; left->maintain(); return left;}void split(node* o, int k, node* &left, node* &right){ splay(o, k); left = o; right = o->ch[1]; o->ch[1] = null; left->maintain();}node seq[N];node* build(int l, int r,int &n){ if(l > r) return null; if(l == r) { node *tmp = &seq[++n]; tmp->s = 1; tmp->v = n-1; tmp->ch[0] = tmp->ch[1] = null; tmp->flip = false; return tmp; } int mid = (l + r) >> 1; node *L=build(l,mid-1,n); node *tmp=&seq[++n]; tmp->ch[0] = L; tmp->flip = false; tmp->v = n-1; tmp->ch[1] = build(mid + 1, r,n); tmp->maintain(); return tmp;}void init(int n){ null->s = 0; int num=0; root = build(1, n + 1,num);}void print(node *o){ if(o == null) return; o->pushdown(); print(o->ch[0]); if(o->v > 0) printf("%d\n", o->v); print(o->ch[1]);}int main(){#ifdef PKWV freopen("in.in", "r", stdin);#endif // PKWV int n, m; scanf("%d%d", &n, &m); init(n); while(m--) { int a, b; scanf("%d%d", &a, &b); node *left, *right; node *l, *r; split(root, a, left, right); split(right, b - a + 1, l, r); l->flip ^= 1; root = merge(merge(left, r), l); } print(root); return 0;}
0 0
- uva 11922 - Permutation Transformer
- uva 11922 Permutation Transformer
- UVA 11922 Permutation Transformer Splay
- UVA 11922 Permutation Transformer(splay)
- UVa 11922 Permutation Transformer(splay)
- UVA 11922 Permutation Transformer [Spaly]
- UVA 11922 Permutation Transformer 伸展树
- 【splay tree】 UVA 11922 Permutation Transformer
- 【UVA】11922 Permutation Transformer 伸展树
- uva 11922 - Permutation Transformer(伸展树)
- UVa 11922 - Permutation Transformer (Splay)
- UVA 11922 Permutation Transformer(Splay Tree)
- UVA 11922 Permutation Transformer(splay树)
- Permutation Transformer+uva+splay树
- UVA 11922 Permutation Transformer(伸展树 Splay Tree)
- uva 11922 Permutation Transformer(Splay tree,懒标记传递)
- UVA 11922 Permutation Transformer Splay 区间翻转 + 区间合并
- UVA 11922 Permutation Transformer (Splay 区间翻转 + 复制粘贴)
- android拦截短信并屏蔽系统的Notification
- 做个开头
- PHP 学习笔记
- java学习笔记17
- 使用Java求对称数
- uva 11922 Permutation Transformer
- 使用Ant一步一步压缩混淆Cocos2d-html5游戏
- UML 基础: 序列图
- 有符号类型的最小负数的补码的由来
- rt5350 gpio的使用
- 一种避免内存碎片的小技巧
- VC6和VS2010运行的不同总结(持续更新)
- http://www.felixcloutier.com/x86/
- 操作系统相关