因為線段樹支援區間修改查詢,平衡樹支援查詢第k大,乙個數的排名,乙個數的前驅、後繼。所以選擇兩個資料結構套在一起。
#include
#include
#include
using namespace std;
int n,m,sz,tmp;
int a[200005],root[200005];
struct tree
tree[3000005];
void update(int &t)
void lturn(int &t)//左旋
void rturn(int &t)//右旋
void insert(int &w,int
x)//平衡樹插入
tree[w].s++;
if(x==tree[w].num) tree[w].w++;
else
if(x
x); if(tree[tree[w].l].rndelse
if(tree[w].l*tree[w].r==0) w=tree[w].l+tree[w].r;
else
if(tree[tree[w].l].rndx);
}else
}else
if(x
x); tree[w].s--;
}else
}void build(int w,int l,int r,int
pos,int
x)//建立線段樹
void query_rank(int w,int
x)//查詢排名
else
if(x
x); else
}void ask_rank(int w,int l,int r,int l,int r,int v)//線段樹中尋找
int mid=(l+r)/2;
if(r<=mid) ask_rank(2
*w,l,mid,l,r,v);
else
if(l>mid) ask_rank(2
*w+1,mid+1,r,l,r,v);
else
}void ask_val(int
x,int
y,int z)//二分找到這個值
printf("%d\n",ans);
}void change(int w,int l,int r,int
pos,int x1,int x2)//修改值
void before(int w,int
x)//前驅
else before(tree[w].l,x);
}void after(int w,int
x)//後繼
else after(tree[w].r,x);
}void ask_before(int w,int l,int r,int l,int r,int v)
int mid=(l+r)/2;
if(r<=mid) ask_before(2
*w,l,mid,l,r,v);
else
if(l>mid) ask_before(2
*w+1,mid+1,r,l,r,v);
else
}void ask_after(int w,int l,int r,int l,int r,int v)
int mid=(l+r)/2;
if(r<=mid) ask_after(2
*w,l,mid,l,r,v);
else
if(l>mid) ask_after(2
*w+1,mid+1,r,l,r,v);
else
}int main()
if(op==2)
if(op==3)
if(op==4)
if(op==5)
}return
0;}
Bzoj3196 二逼平衡樹
您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 額,這個題,看了一眼就知道是...
Bzoj3196 二逼平衡樹
您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 1.查詢k在區間內的排名 2.查詢區間內排名為k的值 3.修改某一位值上的數值 4.查詢k在區間內的前驅 前驅定義為小於x,且最大的數 5.查詢k在區間內的後繼 後繼定義為大於x,且最小的數 額,這個題,看了一眼就知道是...
bzoj3196 二逼平衡樹
題目鏈結 平衡樹系列最後一題 坑啊10s時間限制跑了9764ms。還是要學一學bit套主席樹啦。經典的線段樹套treap。至於第一發為什麼要tle 我不會告訴你treap插入的時候忘了旋轉 woc 自認為treap寫的挺好看的 歡迎來噴 1 include2 include3 include4 in...