ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

平衡树板子

2022-07-23 16:34:50  阅读:147  来源: 互联网

标签:sz cnt return int 板子 ls 平衡 root


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有