近期刷题小结10.14-10.19

P3380 【模板】二逼平衡树(树套树)

题意

在这里插入图片描述

方法

线段树套平衡树
查询k的排名:把每个区间的排名加起来 O ( l o g n 2 ) O(log^2_n) O(logn2)
查询排名为k:不能相加,只能二分了 O ( l o g n 3 ) O(log^3_n) O(logn3)
修改:把包含这个数的区间对应的二叉树都修改了 O ( l o g n 2 ) O(log^2_n) O(logn2)
查询前驱:将每个区间的前驱取max O ( l o g n 2 ) O(log^2_n) O(logn2)
查询后继:将每个区间的后继取min O ( l o g n 2 ) O(log^2_n) O(logn2)
时间复杂度 O ( n ∗ l o g n 3 ) O(n*log^3_n) O(nlogn3)
注意一下细节

心得

结构体方便

代码
#include<bits/stdc++.h>
using namespace std;
inline int read(){
   
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){
   if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){
   x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
const int N=1e5+4,inf=2147483647;
int n,m,a[N];
namespace treap{
   
	struct bala{
   
		int w,siz,num,wei,ch[2];
	}t[N*20];
	int tot=0;
	inline int newnode(int w){
   
		t[++tot].w=w;
		t[tot].wei=rand();
		t[tot].num=t[tot].siz=1;
		t[tot].ch[0]=t[tot].ch[1]=0;
		return tot;
	}
	inline void pushup(int p){
   
		t[p].siz=t[t[p].ch[1]].siz+t[t[p].ch[0]].siz+t[p].num;
	}
	inline void rotate(int &p,int d){
   
		int y=t[p].ch[d];
		t[p].ch[d]=t[y].ch[d^1];
		t[y].ch[d^1]=p;
		pushup(p);pushup(y);
		p=y;
	}
	inline void insert(int &p,int w){
   
		if(!p)p=newnode(w);
		else if(t[p].w==w)++t[p].num;
		else if(t[p].w>w){
   
			insert(t[p].ch[0],w);
			if(t[t[p].ch[0]].wei>t[p].wei)rotate(p,0);
		}
		else{
   
			insert(t[p].ch[1],w);
			if(t[t[p].ch[1]].wei>t[p].wei)rotate(p,1);
		}
		pushup(p);
	}
	inline void delet(int &p,int w){
   
		if(t[p].w>w)delet(t[p].ch[0],w);
		else if(t[p].w<w)delet(t[p].ch[1],w);
		else{
   
			if(t[p].num>1)t[p].num--;
			else if(!t[p].ch[0]&&!t[p].ch[1])p=0;
			else if(!t[p].ch[0]){
   
				rotate(p,1);
				delet(t[p].ch[0],w);
			} 
			else if(!t[p].ch[1]){
   
				rotate(p,0);
				delet(t[p].ch[1],w);
			}
			else{
   
				if(t[t[p].ch[0]].wei>t[t[p].ch[1]].wei){
   
					rotate(p,0);
					delet(t[p].ch[1],w);
				}
				else{
   
					rotate(p,1);
					delet(t[p].ch[0],w);
				}
			}
		}
		if(p)pushup(p);
	} 
	inline int queryrank(int p,int k){
   //+1
		if(!p)return 0;
		if(t[p].w>k)return queryrank(t[p].ch[0],k);
		if(t[p].w==k)return t[t[p].ch[0]].siz;
		return t[t[p].ch[0]].siz+t[p
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值