zoukankan      html  css  js  c++  java
  • P3369 【模板】普通平衡树

    Description:

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1.插入x数
    2.删除x数(若有多个相同的数,因只删除一个)
    3.查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
    4.查询排名为x的数
    5.求x的前驱(前驱定义为小于x,且最大的数)
    6.求x的后继(后继定义为大于x,且最小的数)

    Code

    hzh

    #include<bits/stdc++.h>
    #define N 200010
    using namespace std;
    		   //0:左儿子 1:右儿子 
    int dad[N], son[2][N], tot[N], V[N];
    int rt, cnt, n, opt, x;
    void update(int x){
    	//更新节点总数 
    	tot[x] = tot[son[0][x]] + tot[son[1][x]] + 1;
    }
    void rotate(int x){
    	int y = dad[x], z = dad[y];
    	bool t = son[1][y] == x;//son[t][y] == x
    	if(z)son[son[1][z] == y][z] = x;
    	son[t][y] = son[!t][x];
    	son[!t][x] = y;
    	dad[x] = z;
    	dad[y] = x;
    	dad[son[t][y]] = y;
    	update(y);
    	update(x);
    }
    void splay(int x){
    	for(; dad[x]; rotate(x))if(dad[dad[x]])
    		(son[0][dad[x]] == x) ^ 
    		(son[0][dad[dad[x]]] == dad[x]) ?
    		rotate(x) : rotate(dad[x]);
    	rt = x; 
    }
    void insert(int &x, int y){//把y点插入以x为根的splay 
    	if(!x){
    		x = y;
    		return;
    	}
    	if(V[y] <= V[x])
    		insert(son[0][x], y), dad[son[0][x]] = x;
    	else insert(son[1][x], y), dad[son[1][x]] = x;
    	update(x);
    }
    int findkth(int x, int k){//查询以x为根的splay中第k小的数 
    	if(tot[son[0][x]] + 1 == k)
    		return x;
    	if(tot[son[0][x]] >= k)
    		return findkth(son[0][x], k);
    	return findkth(son[1][x], k - tot[son[0][x]] - 1);
    }
    int findkless(int x, int k){
    //找到比k小的最大的点 
    	if(!x)return 0;
    	if(V[x] >= k)
    		return findkless(son[0][x], k);
    	int t = findkless(son[1][x], k);
    	if(t)return t;
    	return x;
    }
    int findkmore(int x, int k){
    //找到比k大的最小的点 
    	if(!x)return 0;
    	if(V[x] <= k)
    		return findkmore(son[1][x], k);
    	int t = findkmore(son[0][x], k);
    	if(t)return t;
    	return x;
    }
    int newpoint(int x){
    	cnt++;
    	son[0][cnt] = son[1][cnt] = 0;
    	dad[cnt] = 0;
    	V[cnt] = x;
    	tot[cnt] = 1;
    	return cnt;
    }
    void output(){
    	printf("%d
    ", rt);
    	for(int i = 1; i <= cnt; i++)
    		printf("%d %d %d %d %d
    ", V[i], dad[i], son[0][i], son[1][i], tot[i]);
    	puts("");
    }
    int main(){
    	scanf("%d", &n);
    	rt = 0;
    	while(n--){
    		scanf("%d%d", &opt, &x);
    		if(opt == 1){
    			int t = newpoint(x);
    			insert(rt, t);
    			//output();
    			splay(t);
    		}
    		if(opt == 2){
    			int t = findkmore(rt, x - 1);
    			splay(t);
    			dad[son[0][t]] = 0;
    			dad[son[1][t]] = 0;
    			int s = son[0][t];
    			if(!s){
    				rt = son[1][t];
    				continue; 
    			}
    			for(; son[1][s]; s = son[1][s]);
    			splay(s);
    			son[1][s] = son[1][t];
    			dad[son[1][t]] = s;
    		}
    		if(opt == 3){
    			int t = findkmore(rt, x - 1);
    			splay(t);
    			printf("%d
    ", tot[son[0][t]] + 1);
    		}
    		if(opt == 4){
    			int t = findkth(rt, x);
    			splay(t);
    			printf("%d
    ", V[t]);
    		}
    		if(opt == 5){
    			int t = findkless(rt, x);
    			splay(t);
    			printf("%d
    ", V[t]);
    		}
    		if(opt == 6){
    			int t = findkmore(rt, x);
    			splay(t);
    			printf("%d
    ", V[t]);
    		}
    	} 
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    AcWing:141. 周期(KMP)
    暑假集训
    AcWing:112. 雷达设备(贪心 + 笛卡尔坐标系化区间)
    AcWing:111. 畜栏预定(贪心 + 小根堆)
    20200207总结
    Miku and Generals(二分图染色+可行性dp)
    20200205总结
    Coding Contest(最小费用最大流)
    Wannafly-Winter-Camp day5总结
    Wannafly-Winter-Camp day4总结
  • 原文地址:https://www.cnblogs.com/Zforw/p/11250686.html
Copyright © 2011-2022 走看看