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

hdu 3487 Play with Chain splay 区间翻转,插入,删除

2017-06-04 19:03 537 查看
题目链接点这里

都是先经典操作。。

但是写的时候要注意,,经过子节点的地方,,,都要pushdown()啊啊啊啊

#include<iostream>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin);
#define mem(x,y) memset(x,y,sizeof(x));
typedef unsigned long long ULL;
typedef long long LL;
#define MX 555555
//数组splay 区间翻转,区间插入,区间删除
int n,m;
int son[MX][2],fa[MX],siz[MX],root,val[MX],lazy[MX],cnt;
void Pushup(int rt) {
int ls=son[rt][0],rs=son[rt][1];
siz[rt]=1;
if(ls) siz[rt]+=siz[ls];
if(rs) siz[rt]+=siz[rs];
}
void Pushdown(int rt) {
if(lazy[rt]) {
if(son[rt][0])lazy[son[rt][0]]^=1;
if(son[rt][1])lazy[son[rt][1]]^=1;
swap(son[rt][0],son[rt][1]);
lazy[rt]=0;
}
}
int New_nod(int f,int v) {
cnt++;
son[cnt][0]=son[cnt][1]=0;
fa[cnt]=f,siz[cnt]=1,val[cnt]=v,lazy[cnt]=0;
return cnt;
}
void Splay_init() {
cnt=0;
root=New_nod(0,-INF);//先加了2个边界点
son[root][1]=New_nod(root,INF);
Pushup(root);
}
void Rotate(int x,int c) { //c==0代表右旋
int nxtf=fa[fa[x]],f=fa[x];
Pushdown(f),Pushdown(x);
if(nxtf!=0)son[nxtf][son[nxtf][0]!=f]=x;
fa[x]=nxtf;
son[f][c]=son[x][!c];
fa[son[x][!c]]=f;
son[x][!c]=f;
fa[f]=x;
Pushup(f);
}
void Splay(int x,int y) { //把x旋转为y的子节点,首先要确保y是x的祖先
Pushdown(x);
while(fa[x]!=y) {
int f=fa[x];
int c1=(son[fa[f]][0]==f),c2=(son[f][0]==x);
if(fa[f]==y)Rotate(x,!c2);
else {
if(c1^c2)Rotate(x,!c2),Rotate(x,c2);
else Rotate(f,!c1),Rotate(x,!c1);;
}
}
Pushup(x);
if(!y)root=x;
}
int path[MX],pathcnt;
void print(int rt) {
if(rt==0)return;
Pushdown(rt);
print(son[rt][0]);
path[pathcnt++]=val[rt];
print(son[rt][1]);
}
int Select(int x) { //找第x点,x不包括边界
x++;
int now=root;
while(1) {
Pushdown(now);
if(siz[son[now][0]]+1==x)return now;
else if(siz[son[now][0]]+1<x)x-=siz[son[now][0]]+1,now=son[now][1];
else now=son[now][0];
}
}
void Update(int l,int r) {
int x=Select(l-1),y=Select(r+1);
Splay(x,0),Splay(y,x);
lazy[son[y][0]]^=1;
//Pushup(y),Pushup(x);
}
int temp[MX];
int Build(int l,int r,int f ) {
if(l>r)return 0;
int m=(l+r)>>1;
int rt=New_nod(f,temp[m]);
son[rt][0]=Build(l,m-1,rt),son[rt][1]=Build(m+1,r,rt);
Pushup(rt);
return rt;
}
void Insert(int w,int n) { //在第w位置之后,插入n个数
int rt=Build(1,n,0);
int x=Select(w),y=Select(w+1);
Splay(x,0),Splay(y,x);
son[y][0]=rt,fa[rt]=y;
Pushup(y),Pushup(x);
}
void Cut(int l,int r,int to) { //吧下标为[l,r]的数移到to后面
int x=Select(l-1),y=Select(r+1);
Splay(x,0),Splay(y,x);
int rt=son[y][0];
son[y][0]=0;
Pushup(y),Pushup(x);
x=Select(to),y=Select(to+1);
Splay(x,0),Splay(y,x);
son[y][0]=rt,fa[rt]=y;
Pushup(y),Pushup(x);
}
int main() {
FIN;
while(cin>>n>>m&&n>0) {
Splay_init();
for(int i=1; i<=n; i++)temp[i]=i;
Insert(0,n);
for(int i=1; i<=m; i++) {
char s[111];
int a,b,c;
scanf("%s",s);
if(s[0]=='C') {
scanf("%d%d%d",&a,&b,&c);
Cut(a,b,c);
} else {
scanf("%d%d",&a,&b);
Update(a,b);
}
}
pathcnt=0;
print(root);
for(int i=1; i<pathcnt-1; i++)
printf("%d%c",path[i],i==pathcnt-2?'\n':' ');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: