Hdu 3487 play the chain
Description
瑶瑶很喜欢玩项链,她有一根项链上面有很多宝石,宝石从1到n编号。
首先,项链上的宝石的编号组成一个序列:1,2,3,...,n。
她喜欢两种操作:
1.CUT a b c:他会先将a至b号宝石切下来,然后接到c号宝石后面,组成一个新的项链。
举个例子,如果n=8,那么这个项链上的宝石编号依次为:1 2 3 4 5 6 7 8;'CUT 3 5 4',首先我们把3到5号宝石切下,项链变成了:1 2 6 7 8;然后接到4号宝石后面,此时的4号宝石为7,所以此时的项链变成了:1 2 6 7 3 4 5 8.
2.FLIP a b:像第一个操作一样我们先将a至b号宝石切下来,然后将其旋转180°,变成与原来相反的链,在插入到项链的相 同位置中。
举个例子,取操作1中的链:1 2 3 4 5 6 7 8,执行FLIP 2 6操作,则项链将变成:1 6 5 4 3 2 7 8.
他想知道经过m个操作之后项链会变成怎样。
Input
对于每一个数据,第一行会有两个整数:n m(1<=n,m<=300000) n代表宝石的个数,m代表操作的个数。
接下来有M行 有两个操作:
CUT A B C //代表CUT操作,1<=A<=B<=N, 0<=C<=N-(B-A+1).
FLIP A B //代表FLIP操作,1<=A<=B<=N.
输出的结尾将会有两个负数,他们不能当做操作.
Output
对于每一个数据,你需要输出N个整数,任两个数字间用一个空格分开,代表最终得到的项链的从1到N的宝石的序列号。
Sample Input
8 2
CUT 3 5 4
FLIP 2 6
-1 -1
Sample Output
1 4 3 7 6 2 5 8
splay区间操作请见浅谈算法——splay
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=3e5;
int n,m;
struct Splay{
#define T(x) (tree[f[x]][1]==x)
int tree[N+10][2],f[N+10],size[N+10];
bool flag[N+10];
int root,cnt;
void clear(){
root=cnt=0;
memset(f,0,sizeof(f));
memset(tree,0,sizeof(tree));
memset(size,0,sizeof(size));
memset(flag,0,sizeof(flag));
}
void pushdown(int x){
if (!flag[x]) return;
swap(tree[x][0],tree[x][1]);
flag[tree[x][0]]^=1;
flag[tree[x][1]]^=1;
flag[x]=0;
}
void write(int x){
if (!x) return;
pushdown(x);
write(tree[x][0]);
if (x<=n) ++cnt!=n?printf("%d ",x):printf("%d\n",x);
write(tree[x][1]);
}
void build(){
root=n+1;
for (int i=1;i<=n;i++) f[i]=i+1,size[i]=i+1,tree[i+1][0]=i;
f[n+2]=1,size[n+2]=1,tree[1][0]=n+2;
size[root]=n+2;
}
void updata(int x){size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}
void move(int x){
int fa=f[x],son=tree[x][T(x)^1];
tree[x][T(x)^1]=fa;
tree[fa][T(x)]=son;
if (son) f[son]=fa;
f[x]=f[fa];
if (f[x]) tree[f[x]][T(fa)]=x;
f[fa]=x;
updata(fa),updata(x);
}
void splay(int x){
while (f[x]){
if (f[f[x]]) T(x)==T(f[x])?move(f[x]):move(x);
move(x);
}
root=x;
}
int find(int x,int i){
if (!i) return 0;
pushdown(i);
if (size[tree[i][0]]+1==x) return i;
if (x<=size[tree[i][0]]) return find(x,tree[i][0]);
return find(x-size[tree[i][0]]-1,tree[i][1]);
}
void flip(){//区间翻转,打个标记即可
int x=read(),y=read();
x=find(x,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
flag[tree[x][1]]^=1;
}
void consert(int x,int fa){//连边
if (tree[f[x]][T(x)]==x) tree[f[x]][T(x)]=0;
f[tree[fa][0]=x]=fa;
}
void up(int x){while (f[x]) updata(x),x=f[x];}//向上更新
void cut(){//区间切断
int x=read(),y=read(),z=read();
x=find(x+1,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
consert(tree[x][0],f[x]);
z=find(z+2,root);
consert(tree[z][0],x);
consert(x,z);
up(x);
}
}T;
char s[10];
int main(){
while (1){
T.clear();
n=read(),m=read();
if (n==-1&&m==-1) break;
T.build();
for (int i=1;i<=m;i++){
scanf("%s",s);
if (s[0]=='F') T.flip();
if (s[0]=='C') T.cut();
}
T.write(T.root);
}
return 0;
}
Hdu 3487 play the chain的更多相关文章
- HDU 3487 Play with Chain(Splay)
题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...
- hdu 3487 Play with Chain
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 YaoYao is fond of playing his chains. He has a c ...
- HDU 3487 Play with Chain | 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 ...
- HDU 3487 Play with Chain 【Splay】
1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将 ...
- HDU 3487:Play with Chain(Splay)
http://acm.hdu.edu.cn/showproblem.php?pid=3487 题意:有两种操作:1.Flip l r ,把 l 到 r 这段区间 reverse.2.Cut a b c ...
- 【HDU 3487】Play with Chain Splay
题意 给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$ Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+ ...
- Play with Chain 【HDU - 3487】【Splay+TLE讲解】
题目链接 很好的一道题,用了三天多的时间,终于知道了我为什么T的原因,也知道了在Splay的同时该怎样子的节约时间,因为Splay本身就是大常数的O(N*logN),我们如果不在各种细节上节约时间,很 ...
- 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集
[题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...
随机推荐
- uva10537 最短路 倒推
题意:知道了,最后需要的,那么就倒着最短路,推出去就可以了. 以最短路的方式来解决.
- 【small项目】MySQL第二天早上第一次连接超时报错,解决方法com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
MySQL第二天早上第一次连接超时报错,解决方法com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link ...
- ZOJ 4016 Mergeable Stack 链表
Mergeable Stack Time Limit: 2 Seconds Memory Limit: 65536 KB Given initially empty stacks, the ...
- hiho一下 第四十九周 欧拉路
http://hihocoder.com/contest/hiho49/problem/1 给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路. 一个无向图存在欧拉路当且仅当 ...
- AtCoder Grand Contest 012 D Colorful Balls
题意: 有N个球排成一行,第i个球颜色为ci, 权为wi, 如果两个同色球权值和 <= X 则它们可以交换: 如果两个异色球权值和 <= Y 则它们可以交换:不限制交换次数,求能到达的颜色 ...
- Codeforces 803F(容斥原理)
题意: 给n个正整数,求有多少个GCD为1的子序列.答案对1e9+7取模. 1<=n<=1e5,数字ai满足1<=ai<=1e5 分析: 设f(x)表示以x为公约数的子序列个数 ...
- Oracle 设置用户密码永不过期
--1.查看用户的proifle,一般是default select username,profile from dba_users; --2.查看概要文件(default)的密码有效期设置 sele ...
- ArcGIS Engine效率探究——要素的添加和删除、属性的读取和更新
ArcGIS Engine效率探究——要素的添加和删除.属性的读取和更新 来自:http://blog.csdn.net/freewaywalker/article/details/23703863 ...
- 基于cocos2d开发的android小游戏——採花仙
/*cocos 2d 已经成为了如今移动端游戏开发的强有力的工具,眼下主流游戏中多採用cocos 2d游戏引擎. 我也尝试了一下该引擎.我是用的是cocos2d-android,以后要移植到Cocos ...
- web前端减少你按刷新的频率
Browsersync 先下载:nodejs ,然后安装完以后,我们在命令行打印 node -v 完成后我们进行以下操作,安装browser-sync ,官网上有详细的教程,请访问:Browsers ...