主席樹 動態區間第k小

2022-06-02 06:30:13 字數 2183 閱讀 2417

模板題在這裡洛谷2617。

閱讀本文需要有主席樹的基礎,也就是通過區間kth的模板題。

靜態整體kth:

sort一下找第k小,時間複雜度\(o(nlogn)\)。

動態整體kth:

權值線段樹維護一下,時間複雜度\(o(nlogn)\)。

靜態區間kth:

主席樹維護,時間複雜度\(o(nlogn)\)。

動態區間kth:

就是本次的標題。

回憶一下主席樹是如何維護靜態區間kth的。

建立可持久化線段樹後,利用字首和的思想查詢區間的kth。

所以我們想對區間kth帶修改操作,字首和是關鍵。

我們在維護普通字首和,支援查詢和修改操作時,用的是什麼資料結構呢?

所以這時候我們大致有乙個概念了,動態主席樹和主席樹在資料結構上已經多少有點不一樣了。

怎麼套是乙個問題,但簡單想想可以發現,我們在外層維護一顆樹狀陣列,樹狀陣列的每個節點(內層)維護權值線段樹(的根節點),可以解決這個問題。

查操作:

所以總的算下來時間複雜度在\(o(n(logn)^2)\)上。

接下來解決一下空間的問題。

我們知道線段樹的空間複雜度是\(o(4n)\)的,也就是\(o(n)\),樹狀陣列的複雜度為\(o(n)\),那麼如此算下來空間複雜度達到了\(o(n^2)\)。

思考一下怎麼優化?

我們剛剛計算的空間複雜度,基於對每個節點都把完整的權值線段樹開出來。

我們查詢/修改操作的規模是\((logn)^2\)級別的。

那是不是可以動態開點。

對於我們能訪問到的節點創立節點,對於不能訪問到的,就不管了。

附\(luogu2617\)**。

#includeusing namespace std;

const int maxn = 1e5+10;

int n, m, a[maxn], b[maxn<<1], len;

struct query

q[maxn];

//1e5的log大概在20左右 20*20=400

int sum[maxn*400];

int ls[maxn*400];

int rs[maxn*400];

int rt[maxn*400];

int tot;

void update_sgt(int &rt, int l, int r, int x, int val)

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

if(x <= mid) update_sgt(ls[rt], l, mid, x, val);

else update_sgt(rs[rt], mid+1, r, x, val);

sum[rt] = sum[ls[rt]] + sum[rs[rt]];

}inline int lowbit(int x)

void update_bit(int pos, int x, int val)

///提取區間線段樹的根節點

int rt1[maxn], rt2[maxn], cnt1, cnt2;

void locate(int l, int r)

int ask(int l, int r, int k)

else

}int main()

char op[2];

for(int i = 1; i <= m; i++)

else

}//數值離散化

sort(b+1, b+1+len);

len = unique(b+1, b+1+len)-b-1;

for(int i = 1; i <= n; i++)

a[i] = lower_bound(b+1, b+len+1, a[i])-b;

for(int i = 1; i <= m; i++)

if(q[i].op) q[i].k = lower_bound(b+1, b+len+1, q[i].k)-b;

//建樹(動態開點形式)

for(int i = 1; i <= n; i++)

update_bit(i, a[i], 1);

for(int i = 1; i <= m; i++)

else

}return 0;

}

主席樹(區間第k小)

k th number 求區間內第k小的數。主席樹的板子題 主席樹左子樹存小值,右邊大值,用sum記錄一下子樹節點個數。對 l,r 的查詢區間,root r root l 1 可得出 l,r 的差值,也就是大小的個數 include include include include include i...

主席樹 區間第k小

主席樹 權值線段樹 可持久化 權值線段樹 在此處指各個數字在某個區間內出現的次數 那麼第一棵權值線段樹會記錄 1,1 的數字出現次數 第n棵權值線段樹會記錄 1,n 的數字出現次數 例 數列為110001 第一棵權值線段樹記錄為tree1 0 0 tree1 1 1 第二棵權值線段樹記錄為tree2...

主席樹 靜態區間第k小

這是個非常經典的主席樹入門題 靜態區間第k小 資料已經過加強,請使用主席樹。同時請注意常數優化 如題,給定n個整數構成的序列,將對於指定的閉區間查詢其區間內的第k小值。輸入格式 第一行包含兩個正整數n m,分別表示序列的長度和查詢的個數。第二行包含n個整數,表示這個序列各項的數字。接下來m行每行包含...