權值線段樹模板 練習題整理(刷題中)

2021-10-21 14:57:50 字數 1889 閱讀 1917

權值線段樹就是把線段樹的每個點權,賦予一定的含義,比如數字出現的次數,數值字首出現的次數,並用區間求和維護乙個字首資訊,比如數字出現的次數,第k大等(不能實現區間第k大),字首第k大等。

權值線段樹本質是線段樹維護桶,桶是一種資料結構。資料結構的用途是以一種特殊方式統計資料,使得我們能夠快速地修改、查詢我們想要的那部分資料。但是一般我們在想要統計一組資料的時候,我們更關注的是這些資料都是什麼。就比如我們現在要統計乙個數列,我們更關心的是這個數列裡到底有那些數,而不是特別關心這些數都出現了幾次。

桶就打破了這個現狀,作為一種「特殊」的資料結構,它所統計的就是每個資料在資料集合中一共出現了多少次

在實現上,由於值域範圍通常較大,權值線段樹會採用離散化或動態開點的策略優化空間。

1、離線處理+離散化

2、因為只有單點修改,所以可以省略pushup函式

3、前驅、後繼的求法

4、按照每個數出現的次數建樹

5、還有其他解法:splay、treap、樹狀陣列+二分,等等

#define ls		i<<1

#define rs i<<1|1

#define mid ((l+r)>>1)

#define lson ls,l,mid

#define rson rs,mid+1,r

const

int maxn=

1e5+7;

int n,m,sum[maxn<<2]

,a[maxn]

,b[maxn]

,c[maxn]

,cnt;

void

add(

int x,

int k,

int i=1,

int l=0,

int r=cnt-1)

intkth

(int x,

int i=1,

int l=0,

int r=cnt-1)

intquery

(int x,

int i=1,

int l=0,

int r=cnt-1)

intmain()

sort

(b,b+cnt)

; cnt=

unique

(b,b+cnt)

-b;for

(int i=

0;i(c[i]!=4

) a[i]

=lower_bound

(b,b+cnt,a[i]

)-b;

for(

int i=

0;i)}

題目大意:給定乙個(每個數的範圍在[1,n])陣列,可以將反覆將陣列第乙個數移到最後一位。求其中的最小逆序數。

1、逆序數的樹狀陣列模板(就是權值線段樹的一種)

2、把a[0]移到最後後,減少逆序數a[0],同時增加逆序數n-a[0]-1個。值變化:ans-a[0]+n-a[0]-1;

const

int maxn=

5e3+5;

int n,a[maxn]

,t[maxn]

,sum;

intlowbit

(int x)

void

add(

int i,

int x)

}int

query

(int i)

return ans;

}int

main()

sum=ans;

for(

int i=

1;i<=n;i++

)printf

("%d\n"

,sum);}

}

待更新

權值線段樹 模板

ps 維護區間和,時間複雜度 o n logn o nlogn o nlog n include using namespace std typedef long long ll define lson l,m,rt 1 define rson m 1,r,rt 1 1 define pushup ...

線段樹練習題一

線段樹練習題一 description 桌子上零散地放著若干個盒子,桌子的後方是一堵牆。如右圖所示。現在從桌子的前方射來一束平行光,把盒子的影子投射到了牆上。問影子的總寬度是多少?分析 給線段樹每個節點增加乙個域cover。cover 1表示該結點所對應的區間被完全覆蓋,cover 0表示該結點所對...

線段樹練習題二

線段樹練習題二 description 桌子上零散地放著若干個不同顏色的盒子,桌子的後方是一堵牆。如右圖所示。問從桌子前方可以看到多少個盒子?假設人站得足夠遠 輸入時,由底向上,從左到右 分析 cover 0表示該區間由多種顏色組成。cover 0表示該區間只有一種單一的顏色cover,最後用個桶統...