您的位置:首页 > 理论基础 > 数据结构算法

splay区间翻转及删除区间,平移区间

2015-12-06 17:27 811 查看
研究了很长时间,花费了一个下午debug,终于调出来了

hdu 3487 play with chain

http://acm.hdu.edu.cn/showproblem.php?pid=3487

两个操作(指针实现)

cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置.

flip l r 把[l,r]翻转(lazy标记,每次交换左右节点)

cut思路:把l-1旋到根,r+1旋到根的右节点,取下这一段;在剩下的序列中找到c,c+1的位置,把c旋到根,c+1旋到右节点,插入。

由平衡树性质易证得是对的(中序遍历恒定)

flip思路:把l-1旋到根,r+1旋到右节点,打上lazy标记。

最后访问的时候需要pushdown.

(中间每次splay,rotate都需要pushdown)

AC代码(调了好久,蒟蒻一枚)

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#define maxn 330000+20
using namespace std;
int n,q;
int cnt=0;
struct node
{
node *f;
node *ch[2];
int size;
int lazy;
int id;
}S[maxn];
node *root;
void pushdown(node *u)
{
if((!u->lazy)||(u==NULL))return ;
if(u->ch[0]!=NULL)u->ch[0]->lazy^=1;
if(u->ch[1]!=NULL)u->ch[1]->lazy^=1;
node *y=u->ch[0];
u->ch[0]=u->ch[1];
u->ch[1]=y;
u->lazy=0;
}
void pushup(node *u)
{
u->size=1;
if(u->ch[0]!=NULL)u->size+=u->ch[0]->size;
if(u->ch[1]!=NULL)u->size+=u->ch[1]->size;
}
void rotate(node *u)
{
node *f=u->f;
if(f==NULL)return ;
pushdown(u);
pushdown(f);
node *ff=f->f;
int d=u==f->ch[1];
int dd=0;
if(ff!=NULL)dd=f==ff->ch[1];

if(u->ch[d^1])u->ch[d^1]->f=f;
f->ch[d]=u->ch[d^1];

/*int size=u->size;
u->size=f->size;
f->size=f->size-size;
if(u->ch[d^1]!=NULL)f->size+=u->ch[d^1]->size;
*/
f->f=u;
u->ch[d^1]=f;

if(ff!=NULL)ff->ch[dd]=u;
u->f=ff;

pushup(f);
pushup(u);
}
void splay(node *u,node *p)
{
pushdown(u);
while(u->f!=p)
{
node *f=u->f;
node *ff=f->f;
if(ff==p)
{
rotate(u);
break;
}
int d=u==f->ch[1];
int dd=f==ff->ch[1];
if(d==dd)rotate(f);
else rotate(u);
rotate(u);
}
pushup(u);
if(p==NULL)root=u;
}
void insert(int id)
{
if(root==NULL)
{
node *y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=NULL;
y->lazy=0;
root=y;
return ;
}
node *u=root;
node *y;
while(1)
{
u->size++;
if(id<u->id)
{
//左边
if(u->ch[0]!=NULL)u=u->ch[0];
else
{
y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=u;
u->ch[0]=y;
y->lazy=0;
break;
}
}
else
{
if(u->ch[1]!=NULL)u=u->ch[1];
else
{
y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=u;
u->ch[1]=y;
y->lazy=0;
break;
}
}
}
splay(y,NULL);
}
char s[10];
node *find (int x)
{
node *u=root;
while(1)
{
int xx=1;
if(u->ch[0]!=NULL)xx+=u->ch[0]->size;
if(xx==x)return u;
if(x<xx)u=u->ch[0];
else
{
x-=xx;
u=u->ch[1];
}
}
}
void cut(int l,int r,int c)
{
node *x=find(l);
node *y=find(r+2);
splay(x,NULL);
splay(y,root);
node *u=root->ch[1]->ch[0];
/*root->size-=u->size;
root->ch[1]->size-=u->size;
*/
root->ch[1]->ch[0]=NULL;
pushup(root->ch[1]);
pushup(root);
//u->f=NULL;
node *yy=find(c+1);
splay(yy,NULL);
node *xx=find(c+2);
splay(xx,root);
//插入
root->ch[1]->ch[0]=u;
u->f=root->ch[1];
//root->ch[1]->size+=u->size;
//root->size+=u->size;
pushup(root->ch[1]);
pushup(root);
}
void flip(int l,int r)
{
node *x=find(l);
node *y=find(r+2);
splay(x,NULL);
splay(y,root);
node *u=root->ch[1]->ch[0];
u->lazy^=1;
}
void dfs(node *u)
{
//printf("debug : %d %d\n",u->size,u->id);
pushdown(u);
if(u->ch[0])dfs(u->ch[0]);
if(u->id!=0&&u->id!=n+1)printf("%d ",u->id);
if(u->ch[1])dfs(u->ch[1]);
}
int main()
{
freopen("hoho.txt","r",stdin);
while(scanf("%d%d",&n,&q)!=EOF&&!(n<0&&q<0))
{
cnt=0;
root=NULL;
for(int i=0;i<=n+1;i++)insert(i);
for(int i=1;i<=q;i++)
{
scanf("%s",s);
if(s[0]=='C')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
cut(a,b,c);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
flip(a,b);
}
}
dfs(root);
printf("\n");
}

return 0;
}

注意控制格式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息