BZOJ3196 二逼平衡樹 線段樹套Splay

2022-09-14 16:18:24 字數 3399 閱讀 2433

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

1.查詢k在區間內的排名

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

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

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

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

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

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

下面有m行,opt表示操作標號

若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的後繼

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

9 64 2 2 1 9 4 0 1 1

2 1 4 3

3 4 10

2 1 4 3

1 2 5 9

4 3 9 5

5 2 8 524

3491.n和m的資料範圍:n,m<=50000

2.序列中每個數的資料範圍:[0,1e8]

3.雖然原題沒有,但事實上5操作的k可能為負數

板子題也沒啥好寫的……找個好看點的板子比如我的抄抄吧

1 #include2 #include3 #include4

#define n (3000000+100)

5using

namespace

std;67

int root[n],sz,father[n],son[n][2];8

intcnt[n],val[n],size[n];

9int

n,m,a[n],ans,maxn;

1011 inline int

read()

1215

while(ch>='

0'&&ch<='9')

16return x*f;17}

1819

struct

splay_tree

2022

void update(int x)

23void new(int x)

24void clear(int x)

25int pre(int root)

26int next(int root)

2728

void rotate(int

x)29

37void splay(int &root,int

x)38 44

int findx(int &root,int

x)45

57 x-=cnt[now];

58 now=son[now][1

];59}60

}61int find(int &root,int

x)62

77 ans+=cnt[now];

78 now=son[now][1

];79}80

}81}82

void insert(int &root,int

x)83

85int now=root,fa=0;86

while (1)87

89 fa=now; now=son[now][x>val[now]];

90if (now==0)91}

92}93void delete(int &root,int

x)94

97if (!son[root][0] && !son[root][1])

98if (!son[root][1])

99if (!son[root][0])

100101

int oldroot=root,pre=pre(root);

102splay(root,pre);

103 son[root][1]=son[oldroot][1

];104 father[son[oldroot][1]]=root;

105clear(oldroot);

106update(root);

107}

108};

109110

struct

segt_tree

111121

int mid=(l+r)>>1

;122 get_rank(node<<1

,l,mid,l1,r1,k);

123 get_rank(node<<1|1,mid+1

,r,l1,r1,k);

124}

125void update(int node,int l,int r,int x,int

k)126

134void pre(int node,int l,int r,int l1,int r1,int

k)135

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

;146 pre(node<<1

,l,mid,l1,r1,k);

147 pre(node<<1|1,mid+1

,r,l1,r1,k);

148}

149void next(int node,int l,int r,int l1,int r1,int

k)150

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

;161 next(node<<1

,l,mid,l1,r1,k);

162 next(node<<1|1,mid+1

,r,l1,r1,k);

163}

164void ins(int node,int l,int r,int x,int

k)165

172}t;

173174

intmain()

175193

case2:

194205 printf("

%d\n

",l-1

);206

break

;207

}208

case3:

209216

case4:

217224

case5:

225232

}233

}234 }

bzoj3196 二逼平衡樹(線段樹 splay)

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

bzoj3196 二逼平衡樹 線段樹套平衡樹

題目描述 寫一種資料結構,來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 輸入格式 第一行兩個數n,m n,m 5...

Bzoj3196 二逼平衡樹

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