您的位置:首页 > 大数据 > 人工智能

【hdu3487】【splay】Play with Chain

2013-03-04 21:53 453 查看
题目大意是一串链子,要求支持两项操作:

1、从链子中切下a-b区间,然后整体插入到位置k的数的后面(注意这里的k是对于切下之后的位置k)。

2、翻转a-b这个区间的数

这道题是典型的splay题目。

具体操作就是:先提取出a-b这一段区间,然后记录一下区间位置,并且清除,然后再提取出第k个数,插入即可。

第二个操作则是使用lazy标记,不断交换左右子树,实现翻转。

代码:

#include<cstdio>
#include<cstring>
#define keyTree ch[ ch[root][1] ][0]
using namespace std;
const int maxn = 300000 + 10;
int n,m;
int num;
int root,top;
struct SplayTree
{
int ch[maxn][2],pre[maxn];
int val[maxn],sz[maxn];
bool reserve[maxn];
void push_up(int x)
{
sz[x] = sz[ ch[x][0] ] + sz[ ch[x][1] ] + 1;
}
void swap(int &a,int &b)
{
int t = a;a = b;b = t;
}
void push_down(int x)
{
if(reserve[x])
{
if(ch[x][0])reserve[ ch[x][0] ] = !reserve[ ch[x][0] ];
if(ch[x][1])reserve[ ch[x][1] ] = !reserve[ ch[x][1] ];
swap(ch[x][0],ch[x][1]);
reserve[x] = false;
}
}
void Rotate(int x,int f)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x])ch[ pre[x] ][ ch[pre[x]][1] == y ] = x;
ch[x][f] = y;
pre[y] = x;
push_up(y);
}
void Splay(int x,int goal)
{
push_down(x);
while(pre[x] != goal)
{
if(pre[pre[x]] == goal)Rotate(x,ch[pre[x]][0] == x);
else
{
int y = pre[x],z = pre[y];
int f = (ch[z][0] == y);
if(ch[y][f] == x)Rotate(x, !f),Rotate(x ,f);
else Rotate(y,f),Rotate(x,f);
}
}
push_up(x);
if(goal == 0)root = x;
}
void RotateTo(int k,int goal)
{
int x = root;
push_down(x);
while(sz[ ch[x][0] ] != k)
{
if(k < sz[ ch[x][0] ])x = ch[x][0];
else
{
k -= (sz[ ch[x][0] ] + 1);
x = ch[x][1];
}
push_down(x);
}
Splay(x,goal);
}
void work(int l,int r,int k)
{
RotateTo(l - 1,0);
RotateTo(r + 1,root);
int tmp = keyTree;
keyTree = 0;
push_up(ch[root][1]);
push_up(root);
RotateTo(k,0);
RotateTo(k + 1,root);
keyTree = tmp;
pre[tmp] = ch[root][1];
push_up(keyTree);
push_up(root);
}
void res(int l,int r)
{
RotateTo(l - 1,0);
RotateTo(r + 1,root);
reserve[ keyTree ] = !reserve[ keyTree ];
}
void output(int x,int n)
{
push_down(x);
if(ch[x][0])output(ch[x][0],n);
if(val[x] >= 1 && val[x] <= n)
{
num++;
if(num == 1)printf("%d",val[x]);
else printf(" %d",val[x]);
}
if(ch[x][1])output(ch[x][1],n);
}
void Newnode(int &x,int c)
{
x = ++top;
ch[x][0] = ch[x][1] = pre[x] = 0;
reserve[x] = false;
val[x] = c;
sz[x] = 1;
}
void makeTree(int &x,int l,int r,int f)
{
if(l > r)return;
int m = (l + r) >> 1;
Newnode(x,m);
makeTree(ch[x][0],l,m - 1,x);
makeTree(ch[x][1],m + 1,r,x);
pre[x] = f;
push_up(x);
}
void init()
{
memset(ch,0,sizeof(ch));
memset(pre,0,sizeof(pre));
memset(val,0,sizeof(val));
ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
root = top = 0;
Newnode(root,-1);
Newnode(ch[root][1],-1);
pre[ch[root][1]] = root;
makeTree(keyTree,1,n,ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
}Spt;
void init()
{
freopen("hdu3487.in","r",stdin);
freopen("hdu3487.out","w",stdout);
}

void readdata()
{
while(scanf("%d%d",&n,&m) != EOF)
{
if(n == -1 && m == -1)continue;
Spt.init();
for(int i = 1;i <= m;i++)
{
char op[2];
int l,r;
scanf("%s",op);
if(op[0] == 'C')
{
int k;
scanf("%d%d%d",&l,&r,&k);
Spt.work(l,r,k);
}
else
{
scanf("%d%d",&l,&r);
Spt.res(l,r);
}
}
num = 0;
Spt.output(root,n);
printf("\n");
}
}

int main()
{
init();
readdata();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: