## Splay 伸展树 bzoj3224 bzoj3223

Splay 伸展树， 平衡树的一种实现方法

splay的精髓在于 rotate函数， 这里不多作介绍， 以及有大牛把原理及实现方法解释的很清楚了，这里只贴一下自己实现的代码，代码参考  ：史上最详尽的平衡树(splay)讲解与模板

bzoj 3224

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e6+100;

int fa[N], ch[N][2], siz[N], cnt[N], key[N];
int sz, root;

inline void update(int x){
siz[x] = cnt[x];
siz[x] += siz[ch[x][0]] + siz[ch[x][1]];
}

inline void Clear(int x){
fa[x] = ch[x][0] = ch[x][1] = siz[x] = cnt[x] = key[x] = 0;
}

inline bool get(int x){
return ch[fa[x]][1] == x;
}

void Rotate(int x){
int old = fa[x], oldf = fa[old], which = get(x);
ch[old][which] = ch[x][which^1], fa[ch[x][which^1]] = old;
ch[x][which^1] = old, fa[old] = x;
fa[x] = oldf;
if(oldf) ch[oldf][ch[oldf][1]==old]=x;
update(old), update(x);
}

void splay(int x){
while(fa[x]){
if(get(x) == get(fa[x]) && fa[fa[x]]) Rotate(fa[x]);
Rotate(x);//cout<<" x \n";
}
root = x;
}

void Insert(int x){
if(root == 0){
sz++, root = cnt[sz] = siz[sz] = 1, key[sz] = x;
return;
}
int now = root, f = 0;
while(1){
if(key[now] == x){
cnt[now]++, update(now), update(f), splay(now); break;
}
f = now, now = ch[now][x>key[now]];
if(now == 0){
sz++, cnt[sz] = 1, key[sz] = x, siz[sz] = 1, fa[sz] = f, ch[f][x>key[f]] = sz;
update(f), splay(sz); break;
}
}
}

inline int finds(int v){
int now = root, ret=0;
while(1){
if(v == key[now]){
ret += siz[ch[now][0]];
splay(now);
return ret+1;
}
if(v < key[now]) now = ch[now][0];
else if(v > key[now]) ret += cnt[now] + siz[ch[now][0]], now = ch[now][1];
}
}

inline int findx(int x){
int now = root;
while(1){
int t = siz[ch[now][0]] + cnt[now];
if(x <= siz[ch[now][0]]) now = ch[now][0];
else if(x <= t) return key[now];
else x -= t, now = ch[now][1];
}
}

inline int pre(){
int now = ch[root][0];
while(ch[now][1]) now = ch[now][1];
return now;
}

inline int nex(){
int now = ch[root][1];//cout<<key[ch[now][1]]<<" u \n";
while(ch[now][0]) now = ch[now][0];
return now;
}

inline void del(int x){//cout<<key[root]<<endl;
finds(x);
if(cnt[root]>1){
cnt[root]--, update(root); return;
}
if(ch[root][0]==0 && ch[root][1]==0){
Clear(root), root =0; return;
}
if(ch[root][0] && ch[root][1]){
int p = pre(), old = root;
splay(p);
fa[ch[old][1]] = root;
ch[root][1] = ch[old][1];
Clear(old), update(root);
return;
}
int old = root;
root = ch[root][ch[root][0]==0], fa[root] = 0, Clear(old);
}
int main(){
int n, opt, x;
scanf("%d", &n);
for (int i=1; i<=n; ++i){
scanf("%d %d",&opt, &x);
switch(opt){
case 1: Insert(x); break;
case 2: del(x); break;
case 3: printf("%d\n",finds(x)); break;
case 4: printf("%d\n",findx(x)); break;
case 5: Insert(x); printf("%d\n", key[pre()]); del(x); break;
case 6: Insert(x); printf("%d\n", key[nex()]); del(x); break;
}
}
return 0;
}

bzoj 3223

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

int siz[N], ch[N][2], cnt[N], key[N], fa[N], lazy[N];
int root, sz, n, m;

void Clear(int x){
siz[x] = ch[x][0] = ch[x][1] = cnt[x] = key[x] = fa[x] = 0;
}

void update(int x){
siz[x] = cnt[x];
siz[x] += siz[ch[x][0]] + siz[ch[x][1]];
}

bool get(int x){
return ch[fa[x]][1] == x;
}

void pushdown(int x){
if(lazy[x]){
swap(ch[x][0], ch[x][1]);
lazy[ch[x][0]] ^= 1, lazy[ch[x][1]] ^= 1;
}
lazy[x] = 0;
}
void Rotate(int x){
pushdown(fa[x]), pushdown(x);
int fx = fa[x], ffx = fa[fx], which = get(x);
ch[fx][which] = ch[x][which^1], fa[ch[x][which^1]] = fx;
ch[x][which^1] = fx, fa[fx] = x;
fa[x] = ffx;
if(ffx) ch[ffx][ch[ffx][1]==fx] = x;
update(fx), update(x);
}

void splay(int x, int goal){
while(fa[x] != goal){
if(get(x)==get(fa[x]) && fa[fa[x]] && fa[fa[x]]!=goal)
Rotate(fa[x]);
Rotate(x);
}
if(goal==0) root = x;
}

int findx(int x){
int now = root;
pushdown(now);
while(1){
int t = cnt[now] + siz[ch[now][0]];
if(x <= siz[ch[now][0]]) now = ch[now][0];
else if(x <= t) return now;
else x -= t, now = ch[now][1];
pushdown(now);
}
}

void change(int l, int r){
int fl = findx(l),  fr = findx(r+2); //cout<<key[fl]<<"qq\n";
splay(fl, 0), splay(fr, root);
lazy[ch[ch[root][1]][0]] ^= 1;
}

void Insert(int x){
if(root == 0){
sz++, root = cnt[sz] = siz[sz] = 1, key[sz] = x;
return;
}
int now = root, f = 0;
while(1){
if(key[now] == x){
cnt[now]++, update(now), update(f), splay(now, 0); break;
}
f = now, now = ch[now][x>key[now]];
if(now == 0){
sz++, cnt[sz] = 1, key[sz] = x, siz[sz] = 1, fa[sz] = f, ch[f][x>key[f]] = sz;
update(f), splay(sz, 0); break;
}
}
}

int build(int l, int r, int f){//cout<<" UU\n";
if(l > r) return 0;
int mid = l+r>>1, u = ++sz;
if(l == r){
cnt[u] = 1, siz[u] = 1, fa[u] = f, key[u] = l-1;
return u;
}
ch[u][0] = build(l, mid-1, u);
ch[u][1] = build(mid+1, r, u);
cnt[u] = 1, siz[u] = 1, fa[u] = f, key[u] = mid-1;
update(u);
return u;
}

void dfs(int x){
if(!x) return;
pushdown(x);
dfs(ch[x][0]);
if(key[x]>=1 && key[x]<=n) printf("%d ", key[x]);
dfs(ch[x][1]);
}

int main(){
scanf("%d %d", &n, &m);
//for(int i=0; i<=n+1; ++i) Insert(i);
root = build(1, n+2, 0);
while(m--){
int l, r;
scanf("%d %d", &l, &r);
change(l, r);
}
dfs(root);
return 0;
}

posted on 2018-03-01 19:01  lazzzy  阅读(123)  评论(0编辑  收藏  举报