您的位置:首页 > 其它

Hdu-3487 Splay树,删除,添加,Lazy延迟标记操作

2015-09-21 16:28 501 查看

HDU_3487

题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的q操作,最后输出操作后的序列:

分析:首先建立初始化的树结构之前,先给n设置个极限范围0和n+1,防止特殊情况下越界,如果反转[a,b],则先把第a-1个数放在根节点,把b+1结点的数放在根节点的右儿子下面,此时根节点的右儿子的左儿子为根的子树就是[a,b]区间,然后把反转标记传递给该子树的根节点,如果剪切区间[a,b]则把第c+1个数旋转到根节点处,然后把根节点的右儿子为子树的最左面的节点旋转到该子树的根,此时把剪掉的子树的根节点连到根节点的右儿子的左儿子上面即可,需要注意的是,push_down和push_up的操作

codes:指针

#include"stdio.h"
#include"iostream"
#include"queue"
#include"string.h"
#define M 3000005
using namespace std;

struct Text
{
int son[M][2],fa[M],flip[M],num[M];
int top;
int root;
vector<int>p;
void init(int n)
{
top=n+2;
for(int i=0;i<=n+2;i++)
{
num[i]=1;
flip[i]=0;
son[i][0]=son[i][1]=-1;
fa[i]=-1;
}
}
void Rotate(int x,int k)
{
int y=fa[x];
if(k==0)
{
son[y][1]=son[x][0];
if(son[y][1]!=-1)
fa[son[y][1]]=y;

push_up(y);
if(son[fa[y]][0]==y)
son[fa[y]][0]=x;
else
son[fa[y]][1]=x;
fa[x]=fa[y];

son[x][0]=y;
fa[y]=x;
}
else
{
son[y][0]=son[x][1];
if(son[y][0]!=-1)
fa[son[y][0]]=y;

push_up(y);
if(son[fa[y]][0]==y)
son[fa[y]][0]=x;
else
son[fa[y]][1]=x;
fa[x]=fa[y];

son[x][1]=y;
fa[y]=x;
}
}
int Find(int k)
{
k++;
int x=root;
while(1)
{
push_down(x);
int temp=getNum(son[x][0])+1;
if(temp==k)break;
else if(k<temp)
x=son[x][0];
else
{
k-=temp;
x=son[x][1];
}
}
return x;
}
void splay(int x,int f)
{
if(x==-1)return;
while(fa[x]!=f)
{
int y=fa[x];
int z=fa[y];
if(z==f)
{
if(son[y][0]==x)
Rotate(x,1);
else
Rotate(x,0);
}
else
{
if(son[z][0]==y)
{
if(son[y][0]==x)
{
Rotate(y,1);
Rotate(x,1);
}
else
{
Rotate(x,0);
Rotate(x,1);
}
}
else
{
if(son[y][1]==x)
{
Rotate(y,0);
Rotate(x,0);
}
else
{
Rotate(x,1);
Rotate(x,0);
}
}
}
}
if(f==top)
root=x;
}
void RotateTo(int x,int f,int type)
{
if(!type)
x=Find(x);
splay(x,f);
push_up(x);
}
void Reversal(int x)
{
if(x==-1)return;
int y=son[x][0];
son[x][0]=son[x][1];
son[x][1]=y;
}
void creat(int l,int r,int k,int f)
{
if(l>r)return;
int mid=(l+r)/2;
if(f==top)
root=mid;
son[f][k]=mid;
fa[mid]=f;
creat(l,mid-1,0,mid);
creat(mid+1,r,1,mid);
push_up(mid);
}
int getNum(int x)
{
if(x==-1)return 0;
return num[x];
}
void push_up(int rt)
{
num[rt]=getNum(son[rt][0])+getNum(son[rt][1])+1;
}
void push_down(int rt)
{
if(rt==-1)return;
if(flip[rt])
{
flip[rt]^=1;
Reversal(rt);
if(son[rt][0]!=-1)
flip[son[rt][0]]^=1;
if(son[rt][1]!=-1)
flip[son[rt][1]]^=1;
}
}
int findLeft(int rt)
{
int x=rt;
while(1)
{
push_down(x);
if(son[x][0]==-1)break;
x=son[x][0];
}
return x;
}
void CUT(int a,int b,int c)
{
RotateTo(a-1,top,0);
RotateTo(b+1,root,0);
int rt=son[son[root][1]][0];
son[son[root][1]][0]=-1;

RotateTo(c,top,0);
int x=findLeft(son[root][1]);
RotateTo(x,root,1);
son[son[root][1]][0]=rt;
fa[rt]=son[root][1];
}
void FLIP(int a,int b)
{
RotateTo(a-1,top,0);
RotateTo(b+1,root,0);
int x=son[son[root][1]][0];
flip[x]^=1;
}
void dfs(int rt,int n)
{
if(rt==-1)return;
push_down(rt);
dfs(son[rt][0],n);
if(rt>=1&&rt<=n)
p.push_back(rt);
dfs(son[rt][1],n);

}
void Output(int n)
{
dfs(root,n);
printf("%d",p[0]);
for(int i=1;i<(int)p.size();i++)
printf(" %d",p[i]);
puts("");
p.clear();
}
}text;
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=-1)
{
if(n==q&&n==-1)break;
text.init(n);
text.creat(0,n+1,0,text.top);
int a,b,c;
char op[10];

while(q--)
{
scanf("%s%d%d",op,&a,&b);
if(op[0]=='C')
{
scanf("%d",&c);
text.CUT(a,b,c);
}
else
text.FLIP(a,b);

}
text.Output(n);

}
return 0;
}

/*
10 5
Cut 2 6 3
Flip 4 9
Flip 5 8
Cut 6 7 3
Flip 4 5

10 5
Flip 4 9
Flip 5 8
Cut 6 7 3
Flip 4 5

10 1
Flip 2 9
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: