平衡树板子
作者:互联网
fhq Treap
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define I inline
#define gc getchar
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
I int read(){
rg char ch = gc();
rg int x = 0, f = 0;
while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
return f ? -x : x;
}
const int N = 1e5 + 5;
int n;
int son[N][2], v[N], tot, poe[N], sz[N], root, x, y, z;
#define ls son[p][0]
#define rs son[p][1]
I void up(const int &p){
sz[p] = sz[ls] + sz[rs] + 1;
}
I int new_node(int a){
sz[++tot] = 1; poe[tot] = rand(); v[tot] = a;
return tot;
}
void split(int p, const int k, int &x, int &y){
if(!p){ x = y = 0; return; }
if(v[p] <= k){
x = p;
split(rs, k, rs, y);
}else{
y = p;
split(ls, k, x, ls);
}
up(p);
}
int merge(int A, int B){
if(!A || !B) return A | B;
if(poe[A] > poe[B]){
son[A][1] = merge(son[A][1], B);
up(A);
return A;
}
son[B][0] = merge(A, son[B][0]);
up(B);
return B;
}
I void insert(int a){
split(root, a, x, y);
root = merge(x, merge(new_node(a), y));
}
I void del(int a){
split(root, a, x, z);
split(x, a - 1, x, y);
y = merge(son[y][0], son[y][1]);
root = merge(merge(x, y), z);
}
I int kth(int p, int k){
if(sz[p] < k) return 0;
while(true){
if(sz[ls] >= k) p = ls;
else if(sz[ls] + 1 == k) return p;
else k -= sz[ls] + 1, p = rs;
}
}
I int pre(int a){
split(root, a - 1, x, y);
int p = x; while(rs) p = rs;
root = merge(x, y);
return p;
}
I int nxt(int a){
split(root, a, x, y);
int p = y; while(ls) p = ls;
root = merge(x, y);
return p;
}
int main(){
srand(time(0));
n = read();
int op, a;
while(n--){
op = read(); a = read();
switch(op){
case 1: insert(a); break;
case 2: del(a); break;
case 3:
split(root, a - 1, x, y);
printf("%d\n", sz[x] + 1);
root = merge(x, y);
break;
case 4: printf("%d\n", v[kth(root, a)]); break;
case 5: printf("%d\n", v[pre(a)]); break;
case 6: printf("%d\n", v[nxt(a)]); break;
}
}
return 0;
}
Splay
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1e5 + 5;
#define rg register
#define gc getchar
#define I inline
I int read(){
rg char ch = gc();
rg int x = 0, f = 0;
while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
return f ? -x : x;
}
int f[N], sz[N], son[N][2], v[N], cnt[N], tot, root;
#define fs(p) (son[f[p]][1] == p)
#define ls son[p][0]
#define rs son[p][1]
void up(int &p){
sz[p] = sz[ls] + sz[rs] + cnt[p];
}
I void rot(int &p){
int fa = f[p], ffa = f[fa];
int c = fs(p), cc = fs(fa);
son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
son[p][c ^ 1] = fa; f[fa] = p;
if(ffa) son[ffa][cc] = p;//
f[p] = ffa;
up(fa); up(p);
}
I void splay(int p, int goal = 0){
if(!p) return;
static int fa, ffa;
while(f[p] ^ goal){
fa = f[p], ffa = f[fa];
if(ffa ^ goal) rot(fs(p) == fs(fa) ? fa : p);
rot(p);
}
if(!goal) root = p;
}
I void find(int x){
int p = root;
while(v[p] ^ x && son[p][x > v[p]]) p = son[p][x > v[p]];
splay(p);
}
I void insert(int x){
int p = root;
while(v[p] ^ x && son[p][x > v[p]]) p = son[p][x > v[p]];
if(v[p] == x){ ++cnt[p]; }
else{
++tot;
if(p) son[p][x > v[p]] = tot;
f[tot] = p;
sz[tot] = cnt[tot] = 1;
v[tot] = x;
p = tot;
}
splay(p);
}
I int pre(int x){
find(x);
if(v[root] < x) return root;
int p = son[root][0];
while(rs) p = rs;
return p;
}
int nxt(int x){
find(x);
if(v[root] > x) return root;
int p = son[root][1];
while(ls) p = ls;
return p;
}
I void del(int x){
find(x);
if(v[root] ^ x) return;
if(cnt[root] > 1){ --sz[root]; --cnt[root]; return; }
if(!son[root][0] || !son[root][1]){ root = son[root][0] | son[root][1]; f[root] = 0; return; }
int last = pre(x), nnxt = nxt(x);
splay(last); splay(nnxt, last);
son[nnxt][0] = 0;
}
I int kth(int k){
int p = root;
if(sz[p] < k) return 0;
while(1){
if(sz[ls] >= k) p = ls;
else if(sz[ls] + cnt[p] >= k) return p;
else k -= sz[ls] + cnt[p], p = rs;
}
}
int n;
int main(){
ios::sync_with_stdio(0);
n = read();
int op, x;
while(n--){
op = read(), x = read();
if(op == 1) insert(x);
if(op == 2) del(x);
if(op == 3) find(x), cout << sz[son[root][0]] + 1 << '\n';
if(op == 4) cout << v[kth(x)] << '\n';
if(op == 5) cout << v[pre(x)] << '\n';
if(op == 6) cout << v[nxt(x)] << '\n';
}
return 0;
}
替罪羊树
#include<bits/stdc++.h>
using namespace std;
#define rg register
inline int read(){
rg char ch=getchar();
rg int x=0,f=0;
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
#define alpha 0.7
struct node{
int del,cnt,sz,val;
node *ls,*rs;
inline bool isbad(){
return cnt*alpha+5<(ls?ls->cnt:0)||cnt*alpha+5<(rs?rs->cnt:0);
}
inline void up(){
cnt=sz=0;
if(ls) cnt+=ls->cnt,sz+=ls->sz;
if(rs) cnt+=rs->cnt,sz+=rs->sz;
sz+=!del;
++cnt;
}
node(int del,int cnt,int sz,int val,node *ls,node *rs):del(del),cnt(cnt),sz(sz),val(val),ls(ls),rs(rs){}
}*root,**badtag;
inline void dfs(node *p,vector<node*> &v){
if(!p) return;
dfs(p->ls,v);
if(!p->del) v.push_back(p);
dfs(p->rs,v);
if(p->del) delete p;
}
inline node* build(int l,int r,vector<node*> &v){
if(l>r) return NULL;
int mid=(l+r)>>1;
node *p=v[mid];
p->ls=build(l,mid-1,v);
p->rs=build(mid+1,r,v);
p->up();
return p;
}
inline void rebuild(node *&p){
vector<node*> v;
dfs(p,v);
p=build(0,v.size()-1,v);
}
inline void insert(int &x,node *&p){
if(!p){
p=new node(0,1,1,x,NULL,NULL);
return;
}
++p->cnt,++p->sz;
if(x<=p->val) insert(x,p->ls);
else insert(x,p->rs);
if(p->isbad()) badtag=&p;
else if(badtag){
p->cnt-=(*badtag)->cnt-(*badtag)->sz;
}
}
inline void insert(int x){
badtag=NULL;
insert(x,root);
if(badtag) rebuild(*badtag);
}
inline int mink(int k){
node *p=root;
int ans=1;
while(p){
if(p->val<k) ans+=(!p->del+(p->ls?p->ls->sz:0)),p=p->rs;
else p=p->ls;
}
return ans;
}
inline int kth(int k){
node *p=root;
while(p){
if(!p->del&&(p->ls?p->ls->sz:0)+1==k) return p->val;
if((p->ls?p->ls->sz:0)>=k) p=p->ls;
else k-=(p->ls?p->ls->sz:0)+!p->del,p=p->rs;
}
}
inline void erase(int k,node *p){
while(p){
--p->sz;
if(!p->del&&(p->ls?p->ls->sz:0)+1==k){
p->del=1;
return;
}
if((p->ls?p->ls->sz:0)>=k) p=p->ls;
else k-=(p->ls?p->ls->sz:0)+!p->del,p=p->rs;
}
}
int n;
int main(){
n=read();
int op,x;
while(n--){
op=read(),x=read();
if(op==1) insert(x);
else if(op==2) erase(mink(x),root);
else if(op==3) printf("%d\n",mink(x));
else if(op==4) printf("%d\n",kth(x));
else if(op==5) printf("%d\n",kth(mink(x)-1));
else if(op==6) printf("%d\n",kth(mink(x+1)));
}
return 0;
}
标签:sz,cnt,return,int,板子,ls,平衡,root 来源: https://www.cnblogs.com/int256/p/16512269.html