• 普通平衡树


    被学弟怼 : "你的博客上没有替罪羊树模板啊?"

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 100010;
    const double alpha = 0.75;
    struct Node{
    	Node *ch[2];
    	int key,siz,cnt;
    	bool exist;
    	void update(){
    		siz = ch[0]->siz + ch[1]->siz + exist;
    		cnt = ch[0]->cnt + ch[1]->cnt + 1;
    	}
    	bool pa(){
    		return (ch[0]->cnt > cnt*alpha + 5) || (ch[1]->cnt > cnt*alpha + 5);
    	}
    };
    struct STree{
    	Node mem_poor[maxn];
    	Node *tail,*root,*null;
    	Node *bc[maxn];
    	int bc_top;
    	Node* NewNode(int key){
    		Node *p = bc_top ? bc[--bc_top] : tail++;
    		p->ch[0] = p->ch[1] = null;p->key = key;
    		p->siz = p->cnt = 1;p->exist = true;
    		return p;
    	}
    	void Travel(Node *p,vector<Node*>&v){
    		if(p == null) return;
    		Travel(p->ch[0],v);
    		if(p->exist) v.push_back(p);
    		else bc[bc_top++] = p;
    		Travel(p->ch[1],v);
    	}
    	Node* Divide(vector<Node*>&v,int l,int r){
    		if(l >= r) return null;
    		int mid = l+r >> 1;
    		Node *p = v[mid];
    		p->ch[0] = Divide(v,l,mid);
    		p->ch[1] = Divide(v,mid+1,r);
    		p->update();return p;
    	}
    	void Rebuild(Node* &p){
    		static vector<Node*>v;v.clear();
    		Travel(p,v);p = Divide(v,0,v.size());
    	}
    	Node** Insert(Node* &p,int val){
    		if(p == null){
    			p = NewNode(val);
    			return &null;
    		}else{
    			++(p->siz);++(p->cnt);
    			Node **res = Insert(p->ch[val >= p->key],val);
    			if(p->pa()) res = &p;
    			return res;
    		}
    	}
    	void Erase(Node *p,int id){
    		--(p->siz);
    		int x = p->ch[0]->siz + p->exist;
    		if(p->exist && id == x){
    			p->exist = false;
    			return;
    		}else{
    			if(id <= x) Erase(p->ch[0],id);
    			else Erase(p->ch[1],id - x);
    		}return;
    	}
    	void init(){
    		tail = mem_poor;
    		null = tail++;
    		null->ch[0] = null->ch[1] = null;
    		null->cnt = null->siz = null->key = 0;
    		root = null;bc_top = 0;
    	}
    	STree(){init();}
    	void Insert(int val){
    		Node** p = Insert(root,val);
    		if(*p != null) Rebuild(*p);
    	}
    	int Rank(int val){
    		Node *nw = root;
    		int ret = 1;
    		while(nw != null){
    			if(nw->key >= val) nw = nw->ch[0];
    			else{
    				ret += nw->ch[0]->siz + nw->exist;
    				nw = nw->ch[1];
    			}
    		}return ret;
    	}
    	int Kth(int k){
    		Node *nw = root;
    		while(nw != null){
    			if(nw->ch[0]->siz + 1 == k && nw->exist) return nw->key;
    			else if(nw->ch[0]->siz >= k) nw = nw->ch[0];
    			else k -= nw->ch[0]->siz + nw->exist,nw = nw->ch[1];
    		}
    	}
    	void Erase(int k){
    		Erase(root,Rank(k));
    		if(root->siz < alpha*root->cnt) Rebuild(root);
    	}
    	void Erase_kth(int k){
    		Erase(root,k);
    		if(root->siz < alpha*root->cnt) Rebuild(root);
    	}
    }Sky;
    int main(){
    	int n;read(n);
    	int k,m;
    	while(n--){
    		read(k);read(m);
    		switch (k){
    			case 1: Sky.Insert(m);break;
    			case 2: Sky.Erase(m);break;
    			case 3:	printf("%d
    ",Sky.Rank(m));break;
    			case 4: printf("%d
    ",Sky.Kth(m));break;
    			case 5: printf("%d
    ",Sky.Kth(Sky.Rank(m)-1));break;
    			case 6: printf("%d
    ",Sky.Kth(Sky.Rank(m+1)));break;
    		}
    	}
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    c# 正则表达式 首字母转大写
    c# WebBrowser获取cookie
    c# 求最小公倍数
    Response.Redirect与Server.Transfer区别-转
    asp 读文件 比较ip
    asp数组的使用
    如何解决#1045
    mysql limit分页查询效率
    Docker 容器管理:rancher
    Docker监控:google/cadvisor
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6973516.html
Copyright © 2020-2023  润新知