• 平衡树板子


    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;
    }
    
  • 相关阅读:
    SpringMvc的执行机制和环境搭建
    Flexbox,更优雅的布局
    Laravel框架 mysql 数据库 —— 基本使用
    在 Windows 上安装 Laravel 5.x
    javascript 中的借鸡生蛋
    由斐波那契数列所引发的性能优化
    成为一名优秀的Web前端开发者
    H5之contenteditable
    ionic 集锦
    vm10虚拟机安装Mac OS X10.10教程[转]
  • 原文地址:https://www.cnblogs.com/int256/p/16512269.html
Copyright © 2020-2023  润新知