题目链接:

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. Java-Hirbernate小结大纲

    Hibernate Hibernate是一个开放源代码的对象关系映射框架 Hibernate的核心接口一共有6个,分别为:Session.SessionFactory.Transaction.Quer ...

  2. 手势交互之GestureDetector

    GsetureDetector 一.交互过程 触屏的一刹那,触发MotionEvent事件 被OnTouchListener监听,在onTouch()中获得MotionEvent对象 GestureD ...

  3. mysql - 初探

    1,查询所有数据库名称: show databases; 2,查询所有表: use database_name; show tables; 3,查询表中的所有字段: desc table_name;

  4. 关于百度 UEditor的使用

    1.文件路径的配置: 注意:在页面上需要指定editor文件所在的路径,否则报错 后面有时间,再说说 kindEditor和  bootstrap3的summernote的  Editor,  fck ...

  5. C#中Dictionary、ArrayList、Hashtable和Array的区别

    IDictionary接口是所有字典类集合的基本接口,该接口与ICollection,IEnumerable接口是所有非泛型类集合的最基本的接口 IEnumerable接口用于公开枚举数,该枚举数支持 ...

  6. IOS开发网络篇之──ASIHTTPRequest详解

    目录 目录 发起一个同步请求 创建一个异步请求 队列请求 请求队列上下文 ASINetworkQueues, 它的delegate提供更为丰富的功能 取消异步请求 安全的内存回收建议 向服务器端上传数 ...

  7. Spring+AOP+Log4j 用注解的方式记录指定某个方法的日志

    一.spring aop execution表达式说明 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义 ...

  8. 矩形嵌套问题-ACM集训

    参考 http://blog.csdn.net/xujinsmile/article/details/7861412 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形 ...

  9. github 分支 合并

    Git如何进行分支管理?      1.创建分支      创建分支很简单:git branch <分支名>      2.切换分支      git checkout <分支名&g ...

  10. 分享29个超赞的响应式Web设计

    原文自:http://www.csdn.net/article/2013-01-16/2813678-responsive-design-websites 最近几年,响应式Web设计不断印入人们眼帘, ...