第一棵伸展树,各种调试模板……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 伸展树的更多相关文章

  1. UVA 11922 Permutation Transformer —— splay伸展树

    题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...

  2. UVA 11922 Permutation Transformer(平衡二叉树)

    Description Write a program to transform the permutation 1, 2, 3,..., n according to m instructions. ...

  3. UVA 11922 Permutation Transformer(Splay Tree)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 [思路] 伸展树+打标记. 用伸展树维护这个序列,使得能 ...

  4. UVA 11922 Permutation Transformer (Splay树)

    题意: 给一个序列,是从1~n共n个的自然数,接下来又m个区间,对于每个区间[a,b],从第a个到第b个从序列中分离出来,翻转后接到尾部.输出最后的序列. 思路: 这次添加了Split和Merge两个 ...

  5. uva 11922 - Permutation Transformer

    splay的题: 学习白书上和网上的代码敲的: #include <cstdio> #include <cstring> #include <cstdlib> #i ...

  6. UVA - 11922 Permutation Transformer (splay)

    题目链接 题意:你的任务是根据m条指令改变排列{!,2,3,...,n}.每条指令(a,b)表示取出第a~b个元素,翻转后添加到排列的尾部.输出最终序列. 解法:splay对区间分裂合并翻转,模板题. ...

  7. uva 11922 Permutation Transforme/splay tree

    原题链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 伸展树的区间翻转剪切... 如下: #include< ...

  8. uva 12003 Array Transformer (线段树套平衡树)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  9. UVA 11525 Permutation ——(线段树,脑筋急转弯)

    只要注意到对于譬如:S1*(k-1)! 因为后面k-1个数字的全排列个数刚好是(k-1)!,那么第一个数字就是没有取过的数字的第(S1+1)个即可.取走这个数字以后这个数字就不能再用了,依次类推即可得 ...

随机推荐

  1. 数据分析≠Hadoop+NoSQL,不妨先看完善现有技术的10条捷径(分享)

            Hadoop让大数据分析走向了大众化,然而它的部署仍需耗费大量的人力和物力.在直奔Hadoop之前,是否已经将现有技术推向极限?这里总结了对Hadoop投资前可以尝试的10个替代方案, ...

  2. iOS学习笔记之typedef

    typedef unsigned long long weiboId; typedef 定义一个使用方便的类型,谓之为“宏定义“. unsigned long long 是一种无符号的长长整型.本应该 ...

  3. Jquery post 传递数组给asp.net mvc方法

    以批量删除数据为例  做批量删除会需要传递要删除的数据ID数组 function RemoveLog(){ var postModel=[]; //遍历复选框获取要删除的数据ID 存放到数组中  $( ...

  4. dom4j增删改查

    //dom4j添加内容,在第一本书上指定位置添加售价 更改保存所有孩子list集合的顺序 @Test public void add1() throws Exception{ //读 SAXReade ...

  5. C#中使用SelectionStart属性指定输入框光标位置

    今天工作中遇到一个小BUG需要修改,需求为在文本框输入的过程中,如果数字是以0开头则自动消除0 如输入012,则显示12 很容易想到在textbox的text changed事件中判断,如果text是 ...

  6. axure7.0 汉化包下载

    下载地址:http://files.cnblogs.com/files/feijian/axure7.0%E4%B8%AD%E6%96%87%E8%AF%AD%E8%A8%80%E6%B1%89%E5 ...

  7. div 布局

    转:http://blog.csdn.net/mercop/article/details/7882000 HTML CSS + DIV实现整体布局 1.技术目标: 开发符合W3C标准的Web页面 理 ...

  8. 编译为 Release 与 Debug 的区别

    class Program { static void Main(string[] args) { DoWork(); } static void DoWork() { new Person().Ru ...

  9. 什么是REST架构(转)

    REST架构风格是全新的针对Web应用的开发风格,是当今世界最成功的互联网超媒体分布式系统架构,它使得人们真正理解了Http协议本来面貌.随着 REST架构成为主流技术,一种全新的互联网网络应用开发的 ...

  10. 01-04-02【Nhibernate (版本3.3.1.4000) 出入江湖】HQL查询

    public IList<Customer> GetAllHql() { IList<Customer> result = null; ISession session = _ ...