複習計畫 主席樹

2021-10-13 10:08:12 字數 3646 閱讀 8039

三類經典應用

一.區間mex

解題思路:對於主席樹,我們維護一顆權值線段樹,並且用來記錄每乙個數最後出現的位置。為什麼這樣做呢?例如現在有序列[3,

1,0,

2,?,

?]

[3,1,0,2,?,?]

[3,1,0

,2,?

,?],那麼對於主席數來說我們維護[1,

4]

[1,4]

[1,4

]的序列,主席樹內容為[3,

2,4,

1,0,

0]

[3,2,4,1,0,0]

[3,2,4

,1,0

,0],那麼如果我們查詢mex

(2,4

)mex(2,4)

mex(2,

4),也就是說我們需要快速在序列中找到乙個小於2的數並且下標最小,並且最後的下標就是答案,顯然下標為3

33的數為1滿足小於2,那麼最後答案就是3。對於這個尋找過程,我們只需要維護乙個區間min

[x

]min[x]

min[x]

表示區間x[l

,r

]x[l,r]

x[l,r]

最後一次修改的最小位置。[l,

r]

[l,r]

[l,r

]即為答案區間,若[l,

r]

[l,r]

[l,r

]中最小的那個位置小於詢問的l

ll,則答案可能在[l,

r]

[l,r]

[l,r

]內由於答案具有單調性,於是我們在主席樹上二分就可以找到最終解了,如果看不懂,模擬一下**過程也大致能明白

const

int n =

2e5+5;

int n , m;

int a[n]

, lst[n]

, tot;

int rt[n<<5]

, lc[n<<5]

, rc[n<<5]

, minn[n<<5]

;int

insert

(int pre,

int l ,

int r,

int k ,

int val)

int mid =

(l + r)

>>1;

if(k <= mid)

lc[now]

=insert

(lc[pre]

, l, mid, k , val)

;else

rc[now]

=insert

(rc[pre]

, mid +

1, r, k, val)

; minn[now]

=min

(minn[lc[now]

], minn[rc[now]])

;return now;

}int

query

(int i,

int l,

int r,

int val)

intmain

(void

)int len = n +1;

rt[0]

=0;for

(int i =

1; i <= n ; i ++

) rt[i]

=insert

(rt[i-1]

,0, len, a[i]

, i)

;while

(m --

)}

二.區間種類數

解題思路:本題和上乙個題的做法類似,都是要考慮最後乙個數出現的位置,只不過這裡是將位置標記為0or

10or1

0or1

,舉個例子就明白了 。現在假設有序列[3,

5,3,

7,6]

[3,5,3,7,6]

[3,5,3

,7,6

] 詢問你 typ

e(1,

5)

type(1,5)

type(1

,5) 那麼對於主席樹我們維護了5個字首序列[1,

0,0,

0,0]

,[1,

1,0,

0,0]

,[0,

1,1,

0,0]

,[0,

1,1,

1,0]

,[0,

1,1,

1,1]

[1,0,0,0,0],[1,1,0,0,0],[0,1,1,0,0],[0,1,1,1,0],[0,1,1,1,1]

[1,0,0

,0,0

],[1

,1,0

,0,0

],[0

,1,1

,0,0

],[0

,1,1

,1,0

],[0

,1,1

,1,1

],顯然我們求一下第五個序列的區間和就是答案了。這裡的主席樹維護的並不是值域桶而是下標桶(如果維護值域桶,那麼直接對序列做差時間複雜度會出現問題,因為你做差後得到的新序列大於1的數需要作為1計算,這個地方需要遍歷[l,r],和暴力就沒有區別了).至於上面描述過程如何實現,看**模擬一下就知道了。

const

int n =

1e6+5;

int n, m;

int a[n]

, last[n]

, tot;

int rt[n <<5]

, lc[n <<5]

, rc[n <<5]

, sum[n <<5]

;int

insert

(int pre ,

int l ,

int r,

int k ,

int val)

int mid =

(l + r)

>>1;

if(k <= mid)

lc[now]

=insert

(lc[pre]

, l, mid, k , val);if

(k > mid)

rc[now]

=insert

(rc[pre]

, mid +

1, r, k , val)

; sum[now]

= sum[lc[now]

]+ sum[rc[now]];

return now;

}int

query

(int i ,

int l ,

int r,

int l ,

int r)

intmain

(void

) last[a[i]

]= i;

} cin >> m;

while

(m --

)}

樹鏈剖分 複習計畫

應用 一.解題思路 該題需要考慮每條邊給答案帶來的貢獻,通過簡單的畫圖和思考我們可以發現,當乙個節點下有偶數個葉子節點時,該節點到父親節點的邊的貢獻為2,若為奇數則為1,那麼最後的答案為n 2 sig ma d u i mod2 0 n 2 sigma du i mod 2 0 n 2 si gma...

網路流複習計畫

既然是複習網路流,那就不會去做水題了吧233 a.bzoj3996 tjoi2015線性代數 看到題就被嚇壞了2333。線性代數根本沒看完好嗎?然後。md轉個模型就是網路流了 題目大意 給定乙個n n 的矩陣b 和乙個1 n 的行向量c 求乙個1 n 的01矩陣a 使 a b c at 最大 a b...

網路流複習計畫

以前一直沒有刻意去練習過網路流的建圖,相當於完全不會網路流。1 usaco4.2 草地排水drainage ditches 最大流 2 清理雪道 最小流 3 有源匯上下界最大流 有源匯上下界最大流模板題 4 有源匯上下界最小流 有源匯上下界最小流 5 bzoj3698 xww的難題 6 士兵占領 7...