主席樹(靜態區間k小值)

2021-09-10 06:56:04 字數 1068 閱讀 5995

主席樹是一種可持久化動態線段樹,常用於求區間k小值問題。

其本質為建n棵字首和線段樹,也就是n個版本,第i個版本囊括區間[1~i],這裡的i指的是第i個數。那麼求第l到第r個數的區間k小時,便可以轉化為求query(r)-query(l-1)。

對於乙個序列,進行排序和unique去重,得到乙個長度為s的元素互不相同的陣列,通過其下標離散化減小空間消耗。易得每顆線段樹大小都為s,重複數字只需數量加一即可。

unique函式詳解:

但這並沒有結束,若是對於n<=200000,每個i開一顆線段樹,空間複雜度得上天。可以發現,第i棵線段樹與第i-1棵並沒有太多節點資訊改變,實際上最多有logn個節點改變。所以,第i棵線段樹可以與第i-1棵線段樹共用資訊相同的節點,可以省下大量浪費的空間。

附上洛谷p3834 【模板】可持久化線段樹 1(主席樹)**:

#includeusing namespace std;

int tree[200001*40];

int ls[200001*40];

int rs[200001*40];

int rt[200001];

int a[200001];

int b[200001];

int n,m,cnt;

int build(int l,int r)

int update(int pre,int l,int r,int x)

int query(int lt,int rt,int l,int r,int k)

int main()

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

int s=unique(b+1,b+n+1)-b-1;

rt[0]=build(1,s);

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

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

}

ps:主席樹時間複雜度為o((n+m)logs),建樹為o(nlogs),修改為o(logs),s為去重後的元素個數。

空間複雜度為o(nlogn+nlogn),空樹o(nlogn),加樹(logn)。

動態主席樹待續...

主席樹 靜態區間第k小

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

主席樹(區間第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...