hdu3487Play with Chain【splay】
2016-04-24 11:01
375 查看
Description
YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.
At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.
He will perform two types of operations:
CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.
For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.
FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.
For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8
He wants to know what the chain looks like after perform m operations. Could you help him?
Input
There will be multiple test cases in a test data.
For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively.
Then m lines follow, each line contains one operation. The command is like this:
CUT a b c // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1).
FLIP a b // Means a FLIP operation, 1 ≤ a < b ≤ n.
The input ends up with two negative numbers, which should not be processed as a case.
Output
For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.
Sample Input
8 2
CUT 3 5 4
FLIP 2 6
-1 -1
Sample Output
1 4 3 7 6 2 5 8
两种操作:
1.减下来一段按顺序贴到某点前面 :就是木板上delete函数和insert函数和在一起了
2.反转区间
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define Key_value ch[ch[root][1]][0]
const int MAXN=300009;
const int INF=0x3f3f3f3f;
int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];
int sum[MAXN],rev[MAXN],same[MAXN];
int lx[MAXN],rx[MAXN],mx[MAXN];
int root,tot1;
int s[MAXN],tot2;
int a[MAXN];
int n,q;
//debug部分
void Treavel(int x)
{
if(x)
{
Treavel(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d, size= %2d, sum=%2d,rev=%2d same=%2d lx=%2d rx=%2d mx=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],size[x],sum[x],rev[x],same[x],lx[x],rx[x],mx[x]);
Treavel(ch[x][1]);
}
}
void debug()
{
printf("root%d\n",root);
Treavel(root);
}
void NewNode(int &r,int father,int k)
{
if(tot2)r=s[tot2--];
else r=++tot1;
pre[r]=father;
ch[r][0]=ch[r][1]=0;
key[r]=k;
sum[r]=k;
rev[r]=same[r]=0;
lx[r]=rx[r]=mx[r]=k;
size[r]=1;
}
void Update_Same(int r,int v)
{
if(!r)return;
key[r]=v;
sum[r]=v*size[r];
lx[r]=rx[r]=mx[r]=max(v,v*size[r]);
same[r]=1;
}
void Update_Rev(int r)
{
if(!r)return;
swap(ch[r][0],ch[r][1]);
swap(lx[r],rx[r]);
rev[r]^=1;//这里要注意,一定是异或1
}
void Push_Up(int r)
{
int lson=ch[r][0],rson=ch[r][1];
size[r]=size[lson]+size[rson]+1;
sum[r]=sum[lson]+sum[rson]+key[r];
lx[r]=max(lx[lson],sum[lson]+key[r]+max(0,lx[rson]));
rx[r]=max(rx[rson],sum[rson]+key[r]+max(0,rx[lson]));
mx[r]=max(0,rx[lson])+key[r]+max(0,lx[rson]);
mx[r]=max(mx[r],max(mx[lson],mx[rson]));
}
void Push_Down(int r)
{
if(same[r])
{
Update_Same(ch[r][0],key[r]);
Update_Same(ch[r][1],key[r]);
same[r]=0;
}
if(rev[r])
{
Update_Rev(ch[r][0]);
Update_Rev(ch[r][1]);
rev[r]=0;
}
}
void Build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
NewNode(x,father,a[mid]);
Build(ch[x][0],l,mid-1,x);
Build(ch[x][1],mid+1,r,x);
Push_Up(x);
}
void Init()
{
root=tot1=tot2=0;
ch[root][0]=ch[root][1]=pre[root]=size[root]=same[root]=rev[root]=sum[root]=key[root]=0;
lx[root]=rx[root]=mx[root]=-INF;
NewNode(root,0,-1);
NewNode(ch[root][1],root,-1);
for(int i=1;i<=n;i++)a[i]=i;
Build(Key_value,1,n,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
void Rotate(int x,int kind)
{
int y=pre[x];
Push_Down(y);
Push_Down(x);
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
void Splay(int r,int goal)
{
Push_Down(r);
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
{
Push_Down(pre[r]);
Push_Down(r);
Rotate(r,ch[pre[r]][0]==r);
}
else
{
Push_Down(pre[pre[r]]);
Push_Down(pre[r]);
Push_Down(r);
int y=pre[r];
int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
Push_Up(r);
if(goal==0)root=r;
}
int Get_Kth(int r,int k)
{
Push_Down(r);
int t=size[ch[r][0]]+1;
if(t==k)return r;
if(t>k)return Get_Kth(ch[r][0],k);
else return Get_Kth(ch[r][1],k-t);
}
//从第pos个数开始连续删除tot个数
void Delete(int pos,int tot,int pos1)
{
Splay(Get_Kth(root,pos),0);
Splay(Get_Kth(root,pos+tot+1),root);
int tmp=Key_value;
Key_value=0;
Push_Up(ch[root][1]);
Push_Up(root);
Splay(Get_Kth(root,pos1+1),0);
Splay(Get_Kth(root,pos1+2),root);
Key_value=tmp;
pre[Key_value]=ch[root][1];
Push_Up(ch[root][1]);
Push_Up(root);
}
//反转
void Reverse(int pos,int tot)
{
Splay(Get_Kth(root,pos),0);
Splay(Get_Kth(root,pos+tot+1),root);
Update_Rev(Key_value);
Push_Up(ch[root][1]);
Push_Up(root);
}
int cnt;
void Inorder(int r)
{
if(!r)return;
Push_Down(r);
Inorder(ch[r][0]);
if(cnt>=1&&cnt<=n)
{
printf("%d",key[r]);
if(cnt<n) printf(" ");
else puts("");
}
cnt++;
Inorder(ch[r][1]);
}
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&q)==2)
{
if(n==-1&&q==-1) break;
Init();
char op[20];
int x,y,z;
while(q--)
{
scanf("%s",op);
if(op[0]=='C')
{
scanf("%d%d%d",&x,&y,&z);
Delete(x,y-x+1,z);
}
else if(op[0]=='F')
{
scanf("%d%d",&x,&y);
Reverse(x,y-x+1);
}
}
cnt=0;
Inorder(root);
}
return 0;
}
YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.
At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.
He will perform two types of operations:
CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.
For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.
FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.
For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8
He wants to know what the chain looks like after perform m operations. Could you help him?
Input
There will be multiple test cases in a test data.
For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively.
Then m lines follow, each line contains one operation. The command is like this:
CUT a b c // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1).
FLIP a b // Means a FLIP operation, 1 ≤ a < b ≤ n.
The input ends up with two negative numbers, which should not be processed as a case.
Output
For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.
Sample Input
8 2
CUT 3 5 4
FLIP 2 6
-1 -1
Sample Output
1 4 3 7 6 2 5 8
两种操作:
1.减下来一段按顺序贴到某点前面 :就是木板上delete函数和insert函数和在一起了
2.反转区间
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define Key_value ch[ch[root][1]][0]
const int MAXN=300009;
const int INF=0x3f3f3f3f;
int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];
int sum[MAXN],rev[MAXN],same[MAXN];
int lx[MAXN],rx[MAXN],mx[MAXN];
int root,tot1;
int s[MAXN],tot2;
int a[MAXN];
int n,q;
//debug部分
void Treavel(int x)
{
if(x)
{
Treavel(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d, size= %2d, sum=%2d,rev=%2d same=%2d lx=%2d rx=%2d mx=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],size[x],sum[x],rev[x],same[x],lx[x],rx[x],mx[x]);
Treavel(ch[x][1]);
}
}
void debug()
{
printf("root%d\n",root);
Treavel(root);
}
void NewNode(int &r,int father,int k)
{
if(tot2)r=s[tot2--];
else r=++tot1;
pre[r]=father;
ch[r][0]=ch[r][1]=0;
key[r]=k;
sum[r]=k;
rev[r]=same[r]=0;
lx[r]=rx[r]=mx[r]=k;
size[r]=1;
}
void Update_Same(int r,int v)
{
if(!r)return;
key[r]=v;
sum[r]=v*size[r];
lx[r]=rx[r]=mx[r]=max(v,v*size[r]);
same[r]=1;
}
void Update_Rev(int r)
{
if(!r)return;
swap(ch[r][0],ch[r][1]);
swap(lx[r],rx[r]);
rev[r]^=1;//这里要注意,一定是异或1
}
void Push_Up(int r)
{
int lson=ch[r][0],rson=ch[r][1];
size[r]=size[lson]+size[rson]+1;
sum[r]=sum[lson]+sum[rson]+key[r];
lx[r]=max(lx[lson],sum[lson]+key[r]+max(0,lx[rson]));
rx[r]=max(rx[rson],sum[rson]+key[r]+max(0,rx[lson]));
mx[r]=max(0,rx[lson])+key[r]+max(0,lx[rson]);
mx[r]=max(mx[r],max(mx[lson],mx[rson]));
}
void Push_Down(int r)
{
if(same[r])
{
Update_Same(ch[r][0],key[r]);
Update_Same(ch[r][1],key[r]);
same[r]=0;
}
if(rev[r])
{
Update_Rev(ch[r][0]);
Update_Rev(ch[r][1]);
rev[r]=0;
}
}
void Build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
NewNode(x,father,a[mid]);
Build(ch[x][0],l,mid-1,x);
Build(ch[x][1],mid+1,r,x);
Push_Up(x);
}
void Init()
{
root=tot1=tot2=0;
ch[root][0]=ch[root][1]=pre[root]=size[root]=same[root]=rev[root]=sum[root]=key[root]=0;
lx[root]=rx[root]=mx[root]=-INF;
NewNode(root,0,-1);
NewNode(ch[root][1],root,-1);
for(int i=1;i<=n;i++)a[i]=i;
Build(Key_value,1,n,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
void Rotate(int x,int kind)
{
int y=pre[x];
Push_Down(y);
Push_Down(x);
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
void Splay(int r,int goal)
{
Push_Down(r);
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
{
Push_Down(pre[r]);
Push_Down(r);
Rotate(r,ch[pre[r]][0]==r);
}
else
{
Push_Down(pre[pre[r]]);
Push_Down(pre[r]);
Push_Down(r);
int y=pre[r];
int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
Push_Up(r);
if(goal==0)root=r;
}
int Get_Kth(int r,int k)
{
Push_Down(r);
int t=size[ch[r][0]]+1;
if(t==k)return r;
if(t>k)return Get_Kth(ch[r][0],k);
else return Get_Kth(ch[r][1],k-t);
}
//从第pos个数开始连续删除tot个数
void Delete(int pos,int tot,int pos1)
{
Splay(Get_Kth(root,pos),0);
Splay(Get_Kth(root,pos+tot+1),root);
int tmp=Key_value;
Key_value=0;
Push_Up(ch[root][1]);
Push_Up(root);
Splay(Get_Kth(root,pos1+1),0);
Splay(Get_Kth(root,pos1+2),root);
Key_value=tmp;
pre[Key_value]=ch[root][1];
Push_Up(ch[root][1]);
Push_Up(root);
}
//反转
void Reverse(int pos,int tot)
{
Splay(Get_Kth(root,pos),0);
Splay(Get_Kth(root,pos+tot+1),root);
Update_Rev(Key_value);
Push_Up(ch[root][1]);
Push_Up(root);
}
int cnt;
void Inorder(int r)
{
if(!r)return;
Push_Down(r);
Inorder(ch[r][0]);
if(cnt>=1&&cnt<=n)
{
printf("%d",key[r]);
if(cnt<n) printf(" ");
else puts("");
}
cnt++;
Inorder(ch[r][1]);
}
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&q)==2)
{
if(n==-1&&q==-1) break;
Init();
char op[20];
int x,y,z;
while(q--)
{
scanf("%s",op);
if(op[0]=='C')
{
scanf("%d%d%d",&x,&y,&z);
Delete(x,y-x+1,z);
}
else if(op[0]=='F')
{
scanf("%d%d",&x,&y);
Reverse(x,y-x+1);
}
}
cnt=0;
Inorder(root);
}
return 0;
}
相关文章推荐
- 计算机视觉和人工智能领域:教程、网站、博客记录(陆续更新)
- spoj16935 Straight Line Spiral Pattern (Act 3)
- TIME_WAIT状态原理
- “人工智能大脑”跳槽记:吴恩达所理解的智能
- 【AI开发第一步】微软认知服务API应用
- http://blog.csdn.net/huang_xw/article/details/7090173
- USACO|Barn Repair|堆|贪心|动态规划
- 详解wait和waitpid函数
- MapInfo启动时,提示the Microsoft jet engine is not available
- 备份Foxmail7.2邮箱
- JetBrains发布了IntelliJ IDEA 2016.1
- rails 笔记
- 通过RAII机制实现资源的自动释放
- #leetcode#70.Climbing Stairs
- 与人工智能相关的创业公司或团队
- 220. Contains Duplicate III
- IBM openblockchain学习(五)--consensus源码分析
- http://blog.csdn.net/fbysss/article/details/8024748
- spoj 16892 Straight Line Spiral Pattern (Act 1)
- disconnected no supported authentication methods available(server sent: publickey,keyboard interae)