UVa 11922 - Permutation Transformer 伸展树
第一棵伸展树,各种调试模板……TVT
对于 1 n 这种查询我处理的不太好,之前序列前后没有添加冗余节点,一直Runtime Error。
后来加上冗余节点之后又出了别的状况,因为多了 0 和 n+1 这两个节点,并且每次截取翻转添加到序列最后,因此无法确定 n+1 这个节点在序列的哪个位置。
比如(括号中的为添加的冗余节点):
(0) 1 2 3 4 5 (6)
我把[3,4]截取翻转添加到序列尾部,会变成这样:
(0)1 2 5 (6)4 3
此时我如果再希望截取[3,4],期望的结果应该是:
1 2 3 4 5
而实际上会变成:
(0)1 2 4 3 (6) 5
我用了一种挺麻烦的方式解决的这个问题:
就是让伸展树在冗余节点n+1之前的位置再分裂一次,每次把截取的序列添加到节点n+1的前面,一直维持n+1在序列最末尾,这样就不会有干扰了。
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- struct Node
- {
- Node *ch[];
- int v, s;
- int flip;
- Node( int v ):v(v)
- {
- ch[] = ch[] = NULL;
- s = ;
- flip = ;
- }
- int cmp( int x ) const
- {
- int t = ( ch[] == NULL ) ? : ch[]->s;
- if ( t >= x ) return ;
- if ( t + == x ) return -;
- return ;
- }
- void maintain()
- {
- s = ;
- if ( ch[] != NULL ) s += ch[]->s;
- if ( ch[] != NULL ) s += ch[]->s;
- return;
- }
- void pushDown()
- {
- if ( flip )
- {
- flip = ;
- swap( ch[], ch[] );
- if ( ch[] != NULL ) ch[]->flip = !ch[]->flip;
- if ( ch[] != NULL ) ch[]->flip = !ch[]->flip;
- }
- }
- };
- int n, m;
- void Rotate( Node* &o, int d ) //d=0 左旋 d=1 右旋
- {
- Node *k = o->ch[ d ^ ];
- o->ch[ d ^ ] = k->ch[d];
- k->ch[d] = o;
- o = k;
- o->ch[d]->maintain();
- o->maintain();
- return;
- }
- void splay( Node* &o, int k )
- {
- o->pushDown();
- int d = o->cmp(k);
- if ( d == )
- {
- if ( o->ch[] != NULL )
- k -= o->ch[]->s;
- --k;
- }
- if ( d != - )
- {
- Node *p = o->ch[d];
- p->pushDown();
- int d2 = p->cmp(k);
- int k2 = k;
- if ( d2 == )
- {
- if ( p->ch[] != NULL )
- k2 -= p->ch[]->s;
- --k2;
- }
- if ( d2 != - )
- {
- splay( p->ch[d2], k2 );
- if ( d == d2 ) Rotate( o, d ^ );
- else Rotate( o->ch[d], d );
- }
- Rotate( o, d ^ );
- }
- return;
- }
- Node *Merge( Node *left, Node *right )
- {
- splay( left, left->s );
- left->ch[] = right;
- left->maintain();
- return left;
- }
- void Split( Node *o, int k, Node* &left, Node* &right )
- {
- splay( o, k );
- left = o;
- right = o->ch[];
- o->ch[] = NULL;
- left->maintain();
- return;
- }
- void build( Node* &o, int l, int r )
- {
- int m = ( l + r ) >> ;
- o = new Node(m);
- if ( l < m ) build( o->ch[], l, m - );
- if ( r > m ) build( o->ch[], m + , r );
- o->maintain();
- return;
- }
- void DFS( Node *cur )
- {
- cur->pushDown();
- if ( cur->ch[] ) DFS( cur->ch[] );
- if ( cur->v && cur->v != n + ) printf( "%d\n", cur->v );
- if ( cur->ch[] ) DFS( cur->ch[] );
- return;
- }
- void DeleteTree( Node *cur )
- {
- if ( cur->ch[] ) DeleteTree( cur->ch[] );
- if ( cur->ch[] ) DeleteTree( cur->ch[] );
- delete cur;
- return;
- }
- Node *root;
- int main()
- {
- while ( ~scanf( "%d%d", &n, &m ) )
- {
- root = NULL;
- build( root, , n + ); //前后各加了一个冗余节点
- while ( m-- )
- {
- int a, b;
- scanf( "%d%d", &a, &b );
- Node *left, *mid, *right, *o, *tmp;
- Split( root, a, left, o );
- Split( o, b - a + , mid, right );
- if ( right->s - > )
- {
- Split( right, right->s - , tmp, o );
- mid->flip ^= ;
- root = Merge( left, Merge( Merge( tmp, mid ), o ) );
- }
- else
- {
- mid->flip ^= ;
- root = Merge( left, Merge( mid, right ) );
- }
- }
- DFS( root );
- DeleteTree( root );
- }
- return ;
- }
UVa 11922 - Permutation Transformer 伸展树的更多相关文章
- UVA 11922 Permutation Transformer —— splay伸展树
题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...
- UVA 11922 Permutation Transformer(平衡二叉树)
Description Write a program to transform the permutation 1, 2, 3,..., n according to m instructions. ...
- UVA 11922 Permutation Transformer(Splay Tree)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 [思路] 伸展树+打标记. 用伸展树维护这个序列,使得能 ...
- UVA 11922 Permutation Transformer (Splay树)
题意: 给一个序列,是从1~n共n个的自然数,接下来又m个区间,对于每个区间[a,b],从第a个到第b个从序列中分离出来,翻转后接到尾部.输出最后的序列. 思路: 这次添加了Split和Merge两个 ...
- uva 11922 - Permutation Transformer
splay的题: 学习白书上和网上的代码敲的: #include <cstdio> #include <cstring> #include <cstdlib> #i ...
- UVA - 11922 Permutation Transformer (splay)
题目链接 题意:你的任务是根据m条指令改变排列{!,2,3,...,n}.每条指令(a,b)表示取出第a~b个元素,翻转后添加到排列的尾部.输出最终序列. 解法:splay对区间分裂合并翻转,模板题. ...
- uva 11922 Permutation Transforme/splay tree
原题链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 伸展树的区间翻转剪切... 如下: #include< ...
- uva 12003 Array Transformer (线段树套平衡树)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- UVA 11525 Permutation ——(线段树,脑筋急转弯)
只要注意到对于譬如:S1*(k-1)! 因为后面k-1个数字的全排列个数刚好是(k-1)!,那么第一个数字就是没有取过的数字的第(S1+1)个即可.取走这个数字以后这个数字就不能再用了,依次类推即可得 ...
随机推荐
- hadoop的核心思想
hadoop的核心思想 1.1.1. hadoop的核心思想 Hadoop包括两大核心,分布式存储系统和分布式计算系统. 1.1.1.1. 分布式存储 为什么数据需要存储在分布式的系统中哪,难道单一的 ...
- Session设置不当导致API变成单线程问题的解决
起因: 最近开发一个项目,有个接口很慢(数据库的问题),然后在执行期间,随手去点了其他功能(调用其他接口),发现不响应了.等那个很慢的接口返回结果了,这个功能才立马返回结果. 这明显是一个问题啊! ...
- JPA学习---第六节:大数据字段映射与字段延迟加载
1.大数据字段所需的注解 @Lob ,例如: @Lobprivate String info; 在mysql中映射产生的字段的类型是longtext:在oracle中是 CLOB @Lobpriva ...
- app进入后台申请10分钟活跃时间-b
IOS允许长时间在后台运行的情况有7种: audio VoIP GPS 下载新闻 和其它附属硬件进行通讯时 使用蓝牙进行通讯时 使用蓝牙共享数据时 除以上情况,程序退出时可能设置短暂运行10分钟 让程 ...
- .net 自然排序方式
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- 2437: [Noi2011]兔兔与蛋蛋 - BZOJ
Description Input 输入的第一行包含两个正整数 n.m.接下来 n行描述初始棋盘.其中第i 行包含 m个字符,每个字符都是大写英文字母"X".大写英文字母" ...
- Remote Desktop manager 连接后无法自动登录
现象: Remote Desktop manager 连接后无法自动登录 用Windows 自带的远程桌面 可以自动登录 解决方法: 在指定站点 右键 Edit Entry. 如下图处打勾就可以了.
- 【Asp.Net MVC--资料汇总】杂七杂八
Html.RenderPartial与Html.RenderAction的区别 http://blog.sina.com.cn/s/blog_8278b1800100zkn0.html ASP.NET ...
- 【EntityFramwork--处理数据并发问题】
EntityFramwork--处理数据并发问题时支持乐观并发,即假定最佳场景(这里是指数据在更新过程中没有发生变化) 具体看<Beginning ASP.NET 4.5 Databases&g ...
- vc6命令行编译工程方法
查vc++ 6.0 的 msdn找到下面的命令: msdev FileName [/MAKE "ProjectName – ConfigName | ALL"] [/REBUILD ...