HDU3487 play with chain
题目大意:给出1到n的有序数列,现在有两个操作:
1.CUT a b c 把第a到第b个数剪切下来,放到剩下的第c个数的后边。
2.FLIP a b 把第a到第b个数反转。
经过总共m次操作后,求现在的数列。
n,m<300000
分析:典型的splay题。包含的操作即:查找第k大,剪切,插入,反转等操作。
维护size,rev(反转标记)即可。
通过size可以找到第k大,通过rev做懒标记,可以进行反转。
具体说就是,比如要剪切CUT a,b,c,以先把第a-1个节点splay到根的位置,然后把第b+1个节点spaly到根的右儿子的位置,则a到b这一段就刚好是根的右儿子的左子树了,然后把它剪切下来。再把第c节点splay到根的位置,把第c+1个节点splay到根的右儿子的位置,再把刚才剪切的那一段接在根的右儿子的左儿子位置即可。FLIP a b的话,先把第a-1个节点splay到根的位置,把第b+1个节点splay到根的右儿子的位置,然后对根的右儿子的左子树打上懒标记即可。注意:打蓝标记应该是tree[i].rev^=1,而不是tree[i].rev=1。我就是这样wa了一次。
因为splay树的伸展特性,splay树中要增加两个额外的虚拟节点,即头节点和尾节点。初始时把头结点作为根节点,把尾节点作为根的右儿子。有效节点作为根的左儿子的右子树。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 300505
int tot,root,n,m,a,b,c;
char str[];
struct node
{
int val,fa,sz;
bool rev;
int ch[];
}tree[MAXN];
void newnode(int &r,int father,int val)
{
tot++;
r=tot;
tree[tot].fa=father;
tree[tot].val=val;
}
void build(int &root,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/;
newnode(root,father,mid);
build(tree[root].ch[],l,mid-,root);
build(tree[root].ch[],mid+,r,root);
tree[root].sz=tree[tree[root].ch[]].sz+tree[tree[root].ch[]].sz+;
}
void init()
{
tot=root=;
memset(tree,,sizeof tree);
newnode(root,,-);
newnode(tree[root].ch[],root,-);
build(tree[tree[].ch[]].ch[],,n,tree[].ch[]);
tree[tree[].ch[]].sz=tree[tree[tree[].ch[]].ch[]].sz+;
tree[].sz=tree[tree[].ch[]].sz+;
}
void pd(int &r)
{
if(tree[r].rev==)
{swap(tree[r].ch[],tree[r].ch[]);
tree[tree[r].ch[]].rev^=;
tree[tree[r].ch[]].rev^=;
tree[r].rev=;
} }
void pu(int &r)
{
tree[r].sz=tree[tree[r].ch[]].sz+tree[tree[r].ch[]].sz+;
}
void rotato(int &r,bool kind)
{
int y=tree[r].fa;
int yy=tree[y].fa;
if(yy)
{
tree[yy].ch[tree[yy].ch[]==y]=r;
}
tree[r].fa=yy;
tree[tree[r].ch[kind]].fa=y;
tree[y].ch[!kind]=tree[r].ch[kind];
tree[y].fa=r;
tree[r].ch[kind]=y;
pu(y);
pu(r);
}
void splay(int &r,int goal)
{
while(tree[r].fa!=goal)
{
int y=tree[r].fa;
int yy=tree[y].fa;
if(yy==goal)rotato(r,tree[y].ch[]==r);
else
{
int kind=(tree[y].ch[]==r);
if(tree[yy].ch[kind]==y)
{
rotato(r,kind);
rotato(r,!kind);
}
else
{
rotato(y,kind);
rotato(r,kind);
}
}
}
if(goal==)
root=r;
}
int find(int r,int k)
{
pd(r);
if(tree[tree[r].ch[]].sz==k-)
return r;
else if(tree[tree[r].ch[]].sz>k-)
return find(tree[r].ch[],k);
else return find(tree[r].ch[],k-tree[tree[r].ch[]].sz-);
}
void print(int &r)
{
pd(r);
if(tree[r].ch[])
print(tree[r].ch[]);
if(tree[r].val!=-){printf("%d",tree[r].val);if(tot>)printf(" ");tot--;}
if(tree[r].ch[])
print(tree[r].ch[]);
}
int main()
{ while(scanf("%d%d",&n,&m)&&(n>=&&m>=))
{
init();
for(int i=;i<m;i++)
{
scanf("%s",str);
if(str[]=='C')
{
scanf("%d%d%d",&a,&b,&c);
int x1=find(root,a);
int y1=find(root,b+);
splay(x1,);
splay(y1,root);
int t=tree[tree[root].ch[]].ch[];
tree[tree[root].ch[]].ch[]=;
pu(tree[root].ch[]);
pu(root);
x1=find(root,c+);
y1=find(root,c+);
splay(x1,);
splay(y1,root);
tree[tree[root].ch[]].ch[]=t;
tree[t].fa=tree[root].ch[];
pu(tree[root].ch[]);
pu(root);
}
else
{
scanf("%d%d",&a,&b);
int x=find(root,a);
int y=find(root,b+);
splay(x,);
splay(y,root);
tree[tree[tree[root].ch[]].ch[]].rev^=;
}
}
print(root);
printf("\n");
}
}
HDU3487 play with chain的更多相关文章
- HDU--3487 Play with Chain (Splay伸展树)
Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...
- HDU3487 Play With Chain [Splay]
题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n dia ...
- HDU3487 Play with Chain splay 区间反转
HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...
- HDU-3487 Play with Chain Splay tee区间反转,移动
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...
- 【HDU3487】【splay分裂合并】Play with Chain
Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...
- HDU 3487 Play with Chain | Splay
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- hdu3487 splay树
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU 3487 Play with Chain (splay tree)
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- STM32用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain现象和解决方案
现象 CPU: STM32107VC 用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain 如图无法查找到硬件就是CPU 提示1:NO Cortex ...
随机推荐
- PHP 二维码解码 (读取二维码)
#zbar wget http://ncu.dl.sourceforge.net/project/zbar/zbar/0.10/zbar-0.10.tar.bz2 yum install gtk2 g ...
- JavaScipt 源码解析 异步
我们常见的异步操作: 定时器setTimeout postmessage WebWorkor CSS3 动画 XMLHttpRequest HTML5的本地数据 等等- JavaScript要求在与服 ...
- 并发编程 05—— Callable和Future
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- ASP.NET MVC ActionResult的其它返回值
一.ascx页面 场景:要返回代码片断,比如Ajax返回一个子页 我们先新建一个Action public ActionResult Ascx() { return PartialView(); } ...
- 持续集成-sourcetree的安装、使用记录
1.参考 http://blog.sina.com.cn/s/blog_672143a30102vold.html 2.问题-安装sourcetree后,打开时提示下载但是连接不上相应链接 自行下载g ...
- MySQL数据库1 - 基本概念及安装
一.数据管理技术的产生和发展: 1.人工管理阶段 - 效率低,成本高(文字) 2.文件系统阶段 - 易于存储,处理速度快,数据形式丰富(文字,声音,图片...磁带,磁盘) 3.数据库系统阶段 - 易于 ...
- checkbox选中与取消选择
先上代码 <form> 你爱好的运动是?<br/> <input type="checkbox" name="items" val ...
- cassandra 环境搭建
1 下载安装包 http://www.planetcassandra.org/cassandra/?dlink=http://downloads.datastax.com/community/dsc- ...
- MySQL 数据库实现远程连接
1,刚开始我使用的是Navicat for MySQL工具连接远程的mysql的数据库. 报错了.报错信息是 Error 1130: Host '192.168.1.80' is not allowe ...
- POJ 1236 SCC+缩点
题意:一张有向图,一问至少给几个点发送软件,才能让所有点都能收到软件:二问是至少添加几条边才能让整个图是一个连通分量: 分析:一般求连通分量都会求缩点,在这里缩点之后,生成一张新的图,在新的图中求每一 ...