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

Splay 模板题 一 hdu 3487 play with chain

2016-07-11 21:56 573 查看
注意push_down时两个儿子的rev都是^1,而不是变成一.

注意行末不可以有空格.

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int M=300005;
int ch[M][2],siz[M],rev[M],fa[M],val[M];
int n,m,sz,cnt[M];
vector<int>ans;
struct Splay_Tree{
#define key_tree ch[ch[root][1]][0]
int root;
void Newnode(int&rt,int x){
rt=++sz;
rev[rt]=ch[rt][0]=ch[rt][1]=0;
val[rt]=x;cnt[rt]=1;
}
void push_up(int rt){
int l=ch[rt][0],r=ch[rt][1];
siz[rt]=siz[l]+siz[r]+cnt[rt];
}
void push_down(int rt){
if(rev[rt]){
int&l=ch[rt][0],&r=ch[rt][1];
swap(l,r);
rev[l]^=1;
rev[r]^=1;
rev[rt]=0;
}
}
void build(int L,int R,int&rt,int f){
if(L>R) return;
int mid=(L+R)>>1;
Newnode(rt,mid);
fa[rt]=f;
build(L,mid-1,ch[rt][0],rt);
build(mid+1,R,ch[rt][1],rt);
push_up(rt);
}
int find(int k){
int x=root;
while(k){
push_down(x);
if(siz[ch[x][0]]>=k) x=ch[x][0];
else if(siz[ch[x][0]]+cnt[x]<k){
k-=siz[ch[x][0]]+cnt[x];
x=ch[x][1];
}else return x;
}
return x;
}
void Splay(int x,int goal){=
push_down(x);
while(fa[x]!=goal){
int y=fa[x];
if(fa[y]==goal){
push_down(y);push_down(x);
rotate(x,ch[y][0]==x);
}else{
int z=fa[y];
push_down(z);push_down(y);push_down(x);
bool kind=ch[z][0]==y;
if(ch[y][kind]==x) rotate(x,!kind);
else rotate(y,kind);
rotate(x,kind);
}
}
push_up(x);
if(goal==0) root=x;
}
void rotate(int x,bool f){
int y=fa[x];
fa[ch[x][f]]=y;
ch[y][!f]=ch[x][f];
if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y]=x;
fa[x]=fa[y];
ch[x][f]=y;
fa[y]=x;
push_up(y);
}
void cut_to(int a,int b,int c){
int p1=find(a-1),p2=find(b+1);
// printf("%d %d\n",val[p1],val[p2]);
Splay(p1,0);
Splay(p2,root);
int kt=key_tree;
key_tree=0;
// fa[kt]=0;
push_up(ch[root][1]);
push_up(root);
int p3=find(c),p4=find(c+1);
Splay(p3,0);
Splay(p4,root);
key_tree=kt;
fa[kt]=ch[root][1];
push_up(ch[root][1]);
push_up(root);
// Travel(root);
}
void flip(int a,int b){
// printf("%d %d\n",a-1,b+1);
int p1=find(a-1),p2=find(b+1);
Splay(p1,0);
Splay(p2,p1);
rev[key_tree]^=1;
Splay(root,0);
}
void Travel(int x){
if(x){
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d \n",x,ch[x][0],ch[x][1],fa[x],siz[x],val[x]);
Travel(ch[x][0]);
Travel(ch[x][1]);
}
}
void travel(int x){
if(!x) return;
push_down(x);
travel(ch[x][0]);
if(val[x]!=1&&val[x]!=n+2) ans.push_back(val[x]-1);
travel(ch[x][1]);
}
}spt;
char str[20];
void solve(){
sz=0;
ans.clear();
spt.build(1,n+2,spt.root,0);
for(int i=0;i<m;i++){
int a,b,c;
scanf("%s%d%d",str,&a,&b);
a++;b++;
switch(str[0]){
case 'C':
scanf("%d",&c);
c++;
spt.cut_to(a,b,c);
break;
case 'F':
spt.flip(a,b);
break;
}
}
spt.travel(spt.root);
for(int i=0;i<ans.size();i++)
printf("%d%c",ans[i]," \n"[i+1==ans.size()]);
}
int main(){
while(scanf("%d%d",&n,&m),(~n||~m)) solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  play hdu