樹套樹 BZOJ3196 二逼平衡樹

2021-09-03 01:55:00 字數 2053 閱讀 8243

您需要寫一種資料結構(可參考題目標題),來維護乙個有序數列,其中需要提供以下操作:

1.查詢 x在區間內的排名;

2.查詢區間內排名為 k 的值;

3.修改某一位置上的數值;

4.查詢 x 在區間內的前趨(前趨定義為小於 x,且最大的數);

5.查詢 x 在區間內的後繼(後繼定義為大於 x,且最小的數)。

第一行兩個數 n,m,表示長度為 n 的有序序列和 m 個操作。

第二行有 n個數,表示有序序列。

下面有 m 行,每行第乙個數表示操作型別:

1.之後有三個數 l,r,x表示查詢 x在區間 [l,r] 的排名;

2.之後有三個數 l,r,k表示查詢區間 [l,r]內排名為 k的數;

3.之後有兩個數 pos,x表示將 pos位置的數修改為 x;

4.之後有三個數 l,r,x表示查詢區間 [l,r]內 x 的前趨;

5.之後有三個數 l,r,x表示查詢區間 [l,r]內 x 的後繼。

對於操作 1,2,4,5各輸出一行,表示查詢結果。

非常經典的樹套樹題目,這裡採用的是線段樹套平衡樹的做法

對於操作一,我們考慮查詢每一分區間小於查詢值的數的數量累加起來+1即可,查詢過程只需要將其嚴格次小字首轉到根即可

對於操作二,我們考慮二分乙個數,然後參照操作一的做法,查詢所有小於等於二分值的數的數量,可以明白,這是單調遞增的,故二分可行,注意與操作一不一樣的是這裡我們需要將非嚴格次小字首轉到根

對於操作三,直接對每一包含該位置的區間一次刪除,一次插入即可

對於操作四,查詢每一分區間的嚴格次小字首,取較大值

對於操作五,查詢每一分區間的嚴格次大字尾,取較小值

#include#include#include#include#include#include#includeusing namespace std;

int n,m,a[50005],root[200005],sign,ans,op,sum;

struct tree

tree[1650005];

int crepoint(int v,int fa)

int whoson(int x)

void connect(int x,int fa,int son)

void push_up(int k)

void rotate(int x)

void splay(int x,int to,int k)

rotate(x);

} if(!to) root[k]=x;

}void find(int nowroot,int v,int k)

int nex=(v1)

int ls=tree[nowroot].ch[0],rs=tree[nowroot].ch[1];

if(!ls&&!rs)

if(!ls)

if(!rs)

while(tree[ls].ch[1]) ls=tree[ls].ch[1];

splay(ls,0,k);

tree[nowroot].ch[1]=rs;

if(rs) tree[rs].fa=nowroot;

}void build(int k,int l,int r)

int super(int nowroot,int v)

void ask3(int k,int l,int r,int ql,int qr,int v)

int mid=(l+r)>>1;

if(ql<=mid) ask3(k<<1,l,mid,ql,qr,v);

if(mid>1;

if(ql<=mid) ask4(k<<1,l,mid,ql,qr,v);

if(mid>1;

sum=0;

ask2(1,1,n,x,y,mid);

if(sum>=z) ans=mid,r=mid-1;

else l=mid+1;

}printf("%d\n",ans);

} else if(op==3)

else if(op==4)

else

}}

BZOJ 3196 二逼平衡樹 樹套樹

description 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 in...

BZOJ3196二逼平衡樹 樹套樹

description 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 in...

Bzoj3196 二逼平衡樹

您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 額,這個題,看了一眼就知道是...