HDU3487 play with chain

时间:2021-01-09 09:34:35

题目大意:给出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的更多相关文章

  1. HDU--3487 Play with Chain &lpar;Splay伸展树&rpar;

    Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...

  2. HDU3487 Play With Chain &lbrack;Splay&rsqb;

    题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n dia ...

  3. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  4. HDU-3487 Play with Chain Splay tee区间反转&comma;移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...

  5. 【HDU3487】【splay分裂合并】Play with Chain

    Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...

  6. HDU 3487 Play with Chain &vert; Splay

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. hdu3487 splay树

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. HDU 3487 Play with Chain (splay tree&rpar;

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  9. 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 ...

随机推荐

  1. 解决32位plsql连接数据库的问题

    解决32位plsql连接数据库的问题:   安装32位的oracle数据库client版,此地址可下载[http://www.oracle.com/technetwork/database/featu ...

  2. the basic index concept

    Computer Science An Overview _J. Glenn *shear _11th Edition Over the years numerous variations o ...

  3. Objective-C:Foundation框架-常用类-NSMutableString

    NSString是不可变的,不能删除字符或修改字符,它有一个子类NSMutableString,为可变字符串. NSMutableString的两种创建方法: - (id) initWithCapac ...

  4. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2&period;搭建环境-2&period;2安装操作系统CentOS5&period;4

    2.2. 安装操作系统CentOS5.4 两个虚拟机都安装,此步骤在创建虚拟机节点时: 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境所有链接: 1.资源 ...

  5. ExtJs owner&period;componentLayoutCounter问题解

    owner.componentLayoutCounter问题解:listeners : {                                render : function(grid) ...

  6. (poj)3020 Antenna Placement 匹配

    题目链接 : http://poj.org/problem?id=3020 Description The Global Aerial Research Centre has been allotte ...

  7. Apache Avro&num; 1&period;8&period;2 Specification (Avro 1&period;8&period;2规范)二

    h5 { text-indent: 0.71cm; margin-top: 0.49cm; margin-bottom: 0.51cm; direction: ltr; color: #000000; ...

  8. hi3531芯片的标识寄存器

    芯片的标识寄存器 0xee0.0xee4.0xee8.0xeec(基址是0x2005_0000) 系统控制器提供了芯片标识(ID)寄存器SC_SYSID.这个标识寄存器是一个概念上 的32bit 的标 ...

  9. Spring:获取容器中的Bean

    某些情况下我们要获取 IOC 容器中指定注解.类型.名字的 Bean 要获取 IOC 容器中指定条件的 Bean 可以通过 ApplicationContext 相应的方法 @Autowired pr ...

  10. Selenium2&plus;python自动化-查看selenium API

    前面都是点点滴滴的介绍selenium的一些api使用方法,那么selenium的api到底有多少呢?本篇就叫大家如何去查看selenium api,不求人,无需伸手找人要,在自己电脑就有. pydo ...