P3380 模板 二逼平衡樹(樹套樹)

2022-03-01 05:12:27 字數 1797 閱讀 7150

若opt=1 則為操作1,之後有三個數l,r,k 表示查詢k在區間[l,r]的排名

若opt=2 則為操作2,之後有三個數l,r,k 表示查詢區間[l,r]內排名為k的數

若opt=3 則為操作3,之後有兩個數pos,k 表示將pos位置的數修改為k

若opt=4 則為操作4,之後有三個數l,r,k 表示查詢區間[l,r]內k的前驅

若opt=5 則為操作5,之後有三個數l,r,k 表示查詢區間[l,r]內k的後繼

樹套樹區間操作可以用我們熟悉的線段樹

線段樹上每個點 維護對應區間[l,r]的一顆平衡樹

線段樹深度logn,每層要維護n個節點,所以treap的記憶體是nlogn

操作2的話,二分順便用操作1check就好

二分的答案一定是在序列中的 ,複雜度\(log^n\)(真的2b啊,什麼複雜度)

其他具體操作就不囉嗦了(複雜度普遍\(log^n\))

而n=5e4的時候\(log^n\)和\(\sqrt\)基本是相等的(分界線)

線段樹套平衡樹

平衡樹的種類也要選好

fhq-treap這種常數就比較大

普通treap就不錯

splay也闊以

#include #define for(i,a,b) for(int i=a;i<=b;++i)

using namespace std;

const int maxn=5e4+7;

const int inf=0x7fffffff;

inline int read()

int w[maxn];

int ch[maxn*40][2],val[maxn*40],pri[maxn*40],siz[maxn*40],cnt;

namespace fhq_treap

int new_node(int x)

int merge(int x,int y)

} void insert(int &rt,int a)

void delet(int &rt,int a)

int qq(int &rt,int a)

int hj(int &rt,int a)

}struct node e[maxn<<2];

void build(int l,int r,int rt)

void modify(int l,int k,int rt)

int find(int l,int r,int k,int rt)

int qq(int l,int r,int a,int rt)

int mid=(e[rt].l+e[rt].r)>>1,ans=-inf;

if(l<=mid) ans=max(ans,qq(l,r,a,rt<<1));

if(r>mid) ans=max(ans,qq(l,r,a,rt<<1|1));

return ans;

}int hj(int l,int r,int a,int rt)

int mid=(e[rt].l+e[rt].r)>>1,ans=inf;

if(l<=mid) ans=min(ans,hj(l,r,a,rt<<1));

if(r>mid) ans=min(ans,hj(l,r,a,rt<<1|1));

return ans;

}int main()

cout<} else

if(opt==3) else

if(opt==4) else

if(opt==5)

} return 0;

}

洛谷P3380 模板 二逼平衡樹(樹套樹)

查詢k在區間內的排名 查詢區間內排名為k的值 修改某一位值上的數值 查詢k在區間內的前驅 前驅定義為嚴格小於x,且最大的數,若不存在輸出 2147483647 查詢k在區間內的後繼 後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647 輸入格式 第一行兩個數 n,m 表示長度為n的有序...

洛谷P3380 模板 二逼平衡樹(樹套樹)

查詢k在區間內的排名 查詢區間內排名為k的值 修改某一位值上的數值 查詢k在區間內的前驅 前驅定義為嚴格小於x,且最大的數,若不存在輸出 2147483647 查詢k在區間內的後繼 後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647 輸入格式 第一行兩個數 n,m 表示長度為n的有序...

洛谷P3380 模板 二逼平衡樹(樹套樹)

查詢k在區間內的排名 查詢區間內排名為k的值 修改某一位值上的數值 查詢k在區間內的前驅 前驅定義為嚴格小於x,且最大的數,若不存在輸出 2147483647 查詢k在區間內的後繼 後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647 輸入格式 第一行兩個數 n,m 表示長度為n的有序...