题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902

【思路】

伸展树+打标记。

用伸展树维护这个序列,使得能够提供快速的分裂与合并O(logn),利用打标记的方法处理区间翻转的问题。

需要注意的有:

    1)在splay与print中都需要合适地调用pushdown下传标记。

    2)Merge操作应该满足left中所有元素都比right中的元素小,这里的大小定义为序列位置的大小而不是键值v的大小。

    3)因为merge操作不能使left为空所以需要添加一个虚拟节点。

【代码】

 #include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int maxn = +; struct Node{
Node* ch[];
int v,s,flip;
int cmp(int k) {
int d=k-ch[]->s;
if(d==) return -;
return d<=? :;
}
void maintain() {
s=ch[]->s+ch[]->s+;
}
void pushdown() {
if(flip) {
flip=;
swap(ch[],ch[]);
ch[]->flip^=;
ch[]->flip^=;
}
}
};
Node* null=new Node(); void rotate(Node* &o,int d) {
Node* k=o->ch[d^]; o->ch[d^]=k->ch[d]; k->ch[d]=o;
o->maintain(),k->maintain(); o=k;
}
void splay(Node* &o,int k) {
o->pushdown();
int d=o->cmp(k);
if(d==) k-=o->ch[]->s+;
if(d!=-) {
Node* p=o->ch[d];
p->pushdown();
int d2=p->cmp(k);
int k2=d2==? k:k-p->ch[]->s-;
if(d2!=-) {
splay(p->ch[d2],k2);
if(d==d2) rotate(o,d^); else rotate(o->ch[d],d);
}
rotate(o,d^);
}
}
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=left->ch[],left->ch[]=null;
left->maintain();
} struct SplaySequence {
int n;
Node seq[maxn];
Node* root; Node* build(int sz) {
if(!sz) return null;
Node* l=build(sz/);
Node* o=&seq[++n];
o->v=n;
o->ch[]=l;
o->ch[]=build(sz-sz/-);
o->flip=o->s=;
o->maintain();
return o;
}
void init(int sz) {
n=null->s=;
root=build(sz);
}
}spaly; vector<int> ans;
void print(Node* o) {
if(o!=null) {
o->pushdown();
print(o->ch[]);
ans.push_back(o->v);
print(o->ch[]);
}
} int n,m;
int main() {
scanf("%d%d",&n,&m);
spaly.init(n+); //在开始添加虚拟结点
int l,r;
Node *left,*right,*mid;
while(m--) {
scanf("%d%d",&l,&r);
split(spaly.root,l,left,right);
split(right,r-l+,mid,right);
mid->flip^=;
spaly.root = merge(merge(left,right),mid);
}
print(spaly.root);
for(int i=;i<ans.size();i++) printf("%d\n",ans[i]-);
return ;
}

UVA 11922 Permutation Transformer(Splay Tree)的更多相关文章

  1. UVA 11922 Permutation Transformer (Splay树)

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

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

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

  3. 伸展树(Splay Tree)进阶 - 从原理到实现

    目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...

  4. 数据结构(二) --- 伸展树(Splay Tree)

    文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...

  5. 纸上谈兵:伸展树(splay tree)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...

  6. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. 平衡树之伸展树(Splay Tree)题目整理

    目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...

  8. 伸展树(splay tree)

    伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照"最常用者优先"的启发策略.尽管在最坏情况下其单次操作需要 O(n) 时间,但分摊而言仍然 O(log ...

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

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

随机推荐

  1. VS2015 Cordova Ionic移动开发(四)

    一.布局 Ionic模板提供了一个侧边栏菜单示例项目和标签选项卡示例项目.本案例将两个布局进行结合,简单介绍下Ionic的布局.Ionic采用自定义标签和标准Html标签相结合.相对于全部使用div方 ...

  2. JavaScript中style.left与offsetLeft的区别

    今天在制作焦点轮播图的时候,遇到一个问题,在使用style.left获取图片的位置时,怎么也获取不到.换用offsetLeft就能够成功获取到了.虽然实现了我想要的效果,但是还是不甘心啊,没有找到原因 ...

  3. hdoj 1060

    代码: #include <stdio.h>#include <math.h> int main(){    int t;    while(scanf("%d&qu ...

  4. 数组操作- reverse sort each 操作

    reverse reverse 操作符会读取列表(也可能来自数组),并按相反的次序返回该列表. .. ; @barney = reverse(@fred); # 得10,9,8,7,6 .. ; # ...

  5. 从 man 指令起步(info简介)

    前言 小生认为一切指令的学习首先要从帮助入手,深入了解它的功能,即使是在实际项目中我们都离不开它的帮助.因为我们不一定能够记住全部指令的全部的相关功能,因此,查看指令的帮助是我们的不二选择. 正文 下 ...

  6. Invoke()/BeginInvoke()区别

    查看MSDN如下: Control..::.Invoke          ---> 在拥有此控件的基础窗口句柄的线程上执行委托. Control..::.BeginInvoke  ---> ...

  7. 理解CSS Clip属性及用法

    应用Clip属性实现的一个简单效果图: 样式写法: .my-element { position: absolute; clip: rect(10px  350px  170px  0); /* IE ...

  8. 你知道HTML标签设计的本意吗? 把HTML标签用到该用的地方去

    "DIV+CSS"这个词汇不知道害了多少人,也许其提出者本意并没有错,但是跟风者从表现曲解了其意思,认为整个页面就应当是DIV+CSS文件的组合.这样做,对于视觉上并没有什么影响, ...

  9. To Build A Dev Env On Linux(Ubuntu)

    Step1:System Installing 1)use iso image to Step2:Configuration Step3:Software Installing Step4:Other ...

  10. 在 LINQ to Entities 查询中无法构造实体或复杂类型

    public List<CustomerType> GetCustomerTypesBySchemaTypeCode(int schemaTypeCode) { var query = ( ...