1. 程式人生 > 其它 >SDOI2021正睿一輪集訓

SDOI2021正睿一輪集訓

Day 1

一、線段樹

定理:任何一個區間線上段樹上會劃成 \(O(logn)\) 個區間

P4868

二、樹狀陣列

考慮前驅,去掉所有右兒子

每個點維護 \([x-lowbit(x)+1,x]\) 的和

P4868另一種做法

POJ2155 二維樹狀陣列(一維擴二維即可)

三、動態開點線段樹

每次編號,每個節點多維護左兒子和右兒子編號

四、可持久化線段樹

維護所有歷史版本線段樹,每次修改都建一個新點

CF323C

五、線段樹合併

從根開始合併。可持久化就每次合併直接新開一個點即可。

一次合併複雜度是兩棵線段樹公共點個數。每次合併總結點個數會減去公共節點個數,複雜度會加上它,所以均攤複雜度O(logn)。

CF600E(可以DSU on TREE)

六、二維線段樹(可用KDT)

第一維 \([l_1,r_1]\),第二維 \([l_2,r_2]\),維護矩形\((l_1,r_1,l_2,r_2)\)

七、李超樹

支援插入直線,求 \(x\) 處最大值

每個區間維護 \(mid\) 處取值最大的直線,考慮幾種情況分類討論,可以保證每一次都只會下放一條直線到最多一半區間。每個區間不一定是最值,最後單點查詢的時候比較從根到其路徑上 \(O(logn)\) 個直線的最優解。

加線段?李超樹合併?CF932F

八、分塊

兩邊暴力,中間整塊的維護,每次 \(O(B+n/B)\)

HDU6756,不太會

九、莫隊

二維O(n(3/2)),三維O(n(5/3))。

學會如何調整塊大小!奇偶塊排序只會優化大概1/2常數。

CF86D板子

十、帶修莫隊

加一個指標記錄版本,三維莫隊即可。

P1903板子

十一、樹上莫隊

尤拉序:DFS時進入和離開節點時記錄節點編號形成的序列。

st_l到st_r上出現奇數次的點出現在路徑上(無祖先關係就再加LCA)。

P4074 樹上帶修莫隊板子

十二、平衡樹

1.Splay

通過旋轉使整棵樹深度均攤O(logn)。

2.fhqtreap

treap=tree(bst)+heap,滿足堆的性質。

fhqtreap通過分裂和合並維護。

需要修改或者查詢的時候,就分裂開,然後單獨搞,搞完之後再合併即可。每次分裂和合並都是期望O(logn)。

fhqtreap的可持久化就是修改新開一個點就行。可持久化之後就不能用修正值的堆性質了,需要用類似按秩合併的思想用概率合併。

十三、樹鏈剖分

1.輕重鏈剖分

重兒子是子樹大小最大的兒子。

十四、LCT(Link-Cut Tree)

平衡樹使用Splay可以做到均攤O(logn)。維護一個重鏈的森林。

access(x) 把它到根的邊都變為重邊。

makeroot

findroot

split

link

cut

LCT還可以維護子樹資訊。

十五、ETT(Euler Tour Tree)

用平衡樹維護每個點在尤拉序上的括號序列。比較好維護子樹資訊。

把邊改掉相當於對一個子樹在區間上平移。

十六、KDT

十七、綜合練習題

HDU5118,CF1149C,CF482E,CF1192B,P4764

Day 2

構造題專場??

T0熱身題:

偶數無解,左邊加起來n(n-1),右邊加起來n(n-1)/2,模n意義下不相等。

奇數直接取兩個一樣的從小到大排列即可。

T1三元環問題:

考慮上界,猜出一定有一個構造滿足上界。用異或性質一一對應來構造出一組方案。

T2完全圖邊分組:

對於(x,y),放在(x+y) mod (2n-1)這一組,然後對於每個k都取一個i,2k=i (mod (2n-1)。放在這一組。

T3完全圖構造生成樹:

歸納構造,考慮已經構造完2k的情況,考慮2k+1和2k+2的情況如何由2k的情況連幾條邊得到即可。

通過整除之類的性質先判斷上界!

T4平面內三角形:

隨機方向向量不與邊重合,考慮先構造一組方案,然後用凸包消去多餘的點,證明下界2n-2-凸包點數。

T5類魔方變換:

貪心,當前列需要k,那就從後面找個k花幾步放回來。構造交換任意兩個位置的方案即可。

T6序列大小位置相鄰:

劃分成n個段,每次選次小值最小的一個段,刪去整個段,其他段刪去比這個次小值小的數(最多一個),因此必然能選n次,必然有解。

T7向量和為零:不會

T8環上三個顏色:

找中間狀態,先考慮如何從中間狀態轉移。

T9變換:考慮構造一組操作把最大值放在右下角。

T10給uv的較大或較小值:

2-SAT問題,主要就是根據真假關係拆點建邊,然後找強連通分量即可。這個題維護一個上界下界,每個點選擇賦上下界一定不會更劣,轉化為2-SAT求解即可。

CF1375H 值域分塊或值域分治

CF1364E

CF1365G

CF1290D

CF1292E

CF1288F

CF1097E

CF1227G

Day 5

Test 1

A

不能把剩餘油量放到 \({dp}\) 方程裡,所以需要考慮貪心和 \({dp}\) 轉移,設兩個 \({dp}\) 陣列,\({dp_{i,j}}\)表示從i加滿到j,\({dp_{2\ j}}\)表示到j油量為零,僅會有這兩種情況。

考慮對於 \((i,j,k)\) 如何從dp_{i,j}和dp2_{j}轉移到dp_{j,k}和dp2_{k}。分別考慮四種情況轉移即可。

C

30pts:bitset優化LCS O(n^2/w)

dp(i,j)=max(dp(i-1,j,dp(i,j-1),dp(i-1,j-1)+(s[i]==t[j]));

考慮建成一個網格圖,求(a,c)與(b,d)最長路。具體做法:網格圖分治,取中間點,列舉怎麼通過中間分界線。

70pts:好像是預處理T(n)=T(n/2)+O(n1.5),總的O(n1.5)=O(|s|3),總的複雜度O(|s|3+q|s|)。橫豎接連著切保證邊界上的點是根號級別。

Day 3

ICPC 題目選講

2020 上海區域賽

L.Traveling in the grid world

Day 6

組合計數

熱身題1

\(n\) 堆石子,已知每堆石子的數量都介於 \([1,2^m-1]\) 之間且互不相同。給定 \(n,m\),每堆石子中的數量可以任選(但必須滿足上述要求),求有多少種方案可以使得 nim 遊戲下先手取勝。

算後手必勝(異或和為 \(0\)) 的情況。如果沒有非 \(0\) 和不相同的限制,答案就是 \((2^m-1)^{n-1}\),除最後一位以外都可以任選。非 \(0\) 的話,算 \(f_i\) 的時候減去 \(f(i-1)\) 即可。算相同的話,式子就是

\[f_i=\prod_{i=2^m-i+1}^{2^m-1}i-f_{i-1}-(2^m-1)(i-1)f_{i-2} \]

複雜度 \(O(n)\)

熱身題2

給出 \(n\) 個正整數 \(a_i\),你要選出 \(n\) 個正整數 \(b_i\)\(n\) 個正整數 \(d_i\),對於每個 \(i\) 滿足 \(b_i|a_i\)\(d_i|b_i\),求有多少種選法滿足 \(\prod d_i^2\geq \prod b_i\)\(n\leq 100,a_i\leq 10^9\)

首先注意到,\(\prod d_i^2>\prod b_i\)\(\prod d_i^2<\prod b_i\) 是一一對應的,所以現在只需要計算 \(\prod d_i^2=\prod b_i\) 的方案數。對每個質因子跑一邊揹包應該就行了。複雜度 \(O(\sum a_i+(n\log a_i)^2)\)

CF838D

一輪省集出過的 nb 題!

考慮合鏈成環,新加一個 \(n+1\) 號點佔位(不能被某個人佔領)。那麼每個點不被佔領的概率就是 \(\frac{n+1}{n+1-m}\),乘以 \(n+1\) 個位置的方案數 \(2^m(n+1)^m\) 即可。

CTSC2017 吉夫特

首先根據 Lucas 定理,選出來的子序列前面的數必須是後面的數的超集。然後這個東西可以直接列舉超集轉移,複雜度 \(O(3^{\log(\max a_i)})\)。這個東西還可以進行一個非常 nb 的優化:類似分塊,定義 \(f(u,v)\) 表示前 \(9\) 位為 \(u\),後 \(9\) 位為 \(v\) 的超集的 dp 值之和。這樣,計算當前位置的 dp 值的時候,只需要列舉當前 \(a_i\) 的前 \(9\) 位的超集,然後更新的時候只需要列舉後 \(9\) 位的超集。複雜度 \(O(2^9\cdot n)\)

括號序列

求有多少個長度為 \(n\) 的括號序列滿足其所有子序列中最長合法括號子序列的長度恰好為 \(2k\),多組資料。\(T,n\leq 2\times 10^5\)

令左括號為 \(+1\),右括號為 \(-1\)。設字首和陣列為 \(s_i\),那麼最長合法括號子序列的長度為 \(n-s_n+2\min s_i\)。證明大概說的是,考慮一下最少需要拿走多少個括號。從開頭開始,一旦當前左括號個數 \(<\) 右括號個數,那麼接下來的一段右括號就都不行了。這時候直接把起點放到接下來一段右括號後面然後繼續做。最後的時候,起點的高度已經變成 \(\min s_i\) 了,剩下 \(s_n-\min s_i\) 這麼多左括號沒辦法找到匹配的右括號。把這些不能匹配的左右括號扔掉之後,剩下的就能形成合法括號序列了,這個長度是 \(n-s_n+2\min s_i\)

接下來我們考慮列舉 \(t\),那麼 \(s_n=n+2t-2k\),計算 \(\min s_i>t-1\)\(\min s_i>t\) 的方案數相減得到 \(\min s_i=t\) 的方案數。計算 \(\min s_i>t-1\) 的話,相當於畫一個長度為 \(n\),高度從 \(0\)\(s_n\) 的不經過 \(y=t-1\) 的折線。使用那什麼翻折引理,可以得到這個方案數等於沒有任何限制情況下到 \(s_n\) 方案數減去到 \(s_n\) 關於 \(y=t-1\) 對稱的位置的方案數(這個證明我想的是構造一個雙射,使得每一種不合法情況與後面這種的某種情況一一對應就行了)。

然後可以得到這個式子

\[\binom{n}{\frac{n-s_n}{2}}-\binom{n}{\frac{n-(2(t-1)-s_n)}{2}}=\binom{n}{k-t}-\binom{n}{n-k+1} \]

同理可以得到 \(\min s_i>t\) 的方案數為

\[\binom{n}{k-t}-\binom{n}{k} \]

然後一減,發現和 \(t\) 無關……考慮 \(t\) 的取值只需要滿足 \(s_n\geq t\),解得 \(-t\leq n-2k\)。又因為 \(-t\geq 0\),所以 \(t\)\(n-2k+1\) 種取值,也就是說,答案為

\[(n-2k+1)\big(\binom{n}{k}-\binom{n}{k-1}\big) \]

某道省選題

一棵樹,每條邊限制兩個端點的大小關係(限制 \(a_u>a_v\)\(a_u<a_v\))。求有多少種符合要求的排列 \(a\) 滿足整棵樹的限制。\(n<=5000\)

首先考慮一個簡單的問題:樹上所有邊的方向都向下。這種情況就等於樹上拓撲序計數,答案為 \(\frac{n!}{\prod siz_u}\)(證明大概說的是,考慮每個子樹根都必須是子樹內最大的,這個在全排列中的概率是 \(\frac{1}{siz}\))。然後我們考慮一個暴力:對於所有反向的邊,直接不予考慮,這樣樹上會形成若干個連通塊,算出這個答案之後,對所有反向邊進行一個容斥。接下來就要開始 nb 了:我們考慮一個 nb dp,設 \(f(i,j)\) 表示 \(i\) 為根的子樹,當前與 \(i\) 連通的連通塊大小為 \(j\) 的方案數。如果是一個正向邊直接合並,如果是反向邊,那麼有兩種合併方式(容斥,有一種要乘上 \(-1\) 的係數)。直接做這個樹揹包就行,複雜度 \(O(n^2)\)

LOJ 575 不等關係

上邊那個題放到序列上,但是 \(n\leq 10^5\)。考慮還是上邊那個做法,但是你發現這個時候第二維顯得沒那麼重要了,乾脆只開一維,轉移為

\[g_i=\sum_{j=0}^{i-1}\frac{[s_j='>']}{(i-j)!}g(j)(-1)^{cnt_{i-1}-cnt_j} \]

就是你列舉上一次的斷點在哪裡,這裡設 < 為正向,那就是找你欽定的上一次的 > 且是斷點的地方轉移。這個式子看起來很像卷積形式,直接分治 NTT 即可做到 \(O(n\log^2 n)\)

一些關於 Matrix-tree 定理的半懂不懂的話

Matrix-Tree 定理的本質是對環容斥。正常容斥係數應該是 (-1)^環個數。Matrix-Tree 定理刪掉基爾霍夫矩陣中根所在的行列後,任意一個排列如果某一位選了它自己(即選在對角線上),那就說明從出邊中隨便選了一條;否則剩餘的部分會形成若干個環,如果這些環形成的是奇排列則會有 -1 的係數。奇排列就相當於環的總長度減掉環個數是奇數,由於非對角線元素都取了相反數,因此 \((-1)\) 被乘的次數恰好是環的總長度,再乘上奇排列的係數,恰好就是 (-1)^環個數。因此 Matrix-Tree 定理不僅可以用於無向圖,也很容易可以推廣到任意有向圖上。

某道題

給⼀張 \(n\) 個點 \(m\) 條有向帶權邊的有向圖。這張圖的⼀個樹形圖定義為:從 \(m\) 條邊中選出 \(n-1\) 條邊,使得所有點都可以通過這些邊走到 \(n\) 號點。 ⼀個樹形圖的權值定義為這 \(n-1\) 條邊的權值和。求出所有樹形圖的權值和,答案對 \(998244353\) 取模。\(n\leq 500\)

一個經典的加轉乘做法是,把每條邊看作一個一次函式 \(wx+1\),你發現這裡的一次函式乘法(\(\bmod x^2\) 意義下)相當於在一次項係數上加!然後這題要注意,\(ax\) 不一定有逆元的(無常數項),如果遇到了一整列都沒有,這種情況下要對一整行都除以 \(x\),然後把答案乘以 \(x\),當然都是 \(\bmod x^2\) 意義下的。

然後這個題如果沒有考慮 \(ax\) 無逆元的情況,可以構造一個答案為 \(\bmod\) 的倍數的圖。也就引發出了一道構造題:構造一個有向圖,使得以 \(1\) 為根的生成樹個數恰好為 \(k\)\(k\leq 10^{18}\)

首先把 \(k\) 表示成 \(2^p-2^{a1}-2^{a2}-\ldots\) 這樣的,考慮先弄 \(p+1\) 個點,每個點 \(i\)\(i-1\)\(1\) 連邊,這樣生成樹個數就是 \(2^p\)(因為是 DAG)。然後對於某個 \(ai\),考慮把倒數 \(n-ai\) 位置的點到 \(1\) 的邊改成到末尾 \(p+1\) 的邊,這樣就形成一個環了,用對環容斥的方式可以得到答案為 \(k\)

某道集訓題(正睿NOIP集訓Test16-C)

\(y\) 軸正半軸上有 \(n\) 個點 \((0,a_1),\ldots,(0,a_n)\),他們每次可以向右或向下走一格,求最後分別到 \((1,0),\ldots,(n,0)\) 的方案數。\(n,a_i<=10^6\)

首先根據 LGV 引理可以得到答案是求:

\[\left|\begin{array}{cccc} \binom{a_1+1}{1}&\binom{a_1+2}{2}&\cdots&\binom{a_1+n}{n}\\ \binom{a_2+1}{1}&\binom{a_2+2}{2}&\cdots&\binom{a_2+n}{n}\\ \vdots&\vdots&\ddots&\vdots\\ \binom{a_n+1}{1}&\binom{a_n+2}{2}&\cdots&\binom{a_n+n}{n} \end{array}\right| \]

提出公因子來可以得到

\[\frac{\prod (a_i+1)}{1!2!\cdots n!}\left|\begin{array}{cccc} 1&(a_1+2)^{\underline{1}}&\cdots&(a_1+n)^{\underline{n-1}}\\ 1&(a_2+2)^{\underline{1}}&\cdots&(a_2+n)^{\underline{n-1}}\\ \vdots&\vdots&\ddots&\vdots\\ 1&(a_n+2)^{\underline{1}}&\cdots&(a_n+n)^{\underline{n-1}} \end{array}\right| \]

然後有一個結論說的是,任意的矩陣滿足 \(A_{i,j}\)\(a_j\)\(i-1\) 次多項式,都可以消元成以下形式:

\[\frac{\prod (a_i+1)}{1!2!\cdots n!}\left|\begin{array}{cccc} 1&a_1&\cdots&a_1^{n-1}\\ 1&a_2&\cdots&a_2^{n-1}\\ \vdots&\vdots&\ddots&\vdots\\ 1&a_n&\cdots&a_n^{n-1} \end{array}\right| \]

然後這個東西叫做範特蒙德矩陣,行列式就是

\[\prod_{1\leq i<j\leq n}(a_j-a_i) \]

\(g_j\) 表示 \(a_i=j\)\(i\) 的數量,則原式可以寫成

\[\sum_{k}k\big(\sum_{j=k}^{10^6}g_j g_{j-k}\big) \]

直接卷積即可。複雜度 \(O(V\log V)\)

Day 7

圖論與網路流

一、強連通分量

  1. 強連通分量是一個極大強連通子圖。

  2. 忘了……

  3. kosaraju演算法縮點:dfs求post-order(dfs回溯順序),然後邊反向、用post-order反序dfs,每一次搜到的點都在一個強連通分量裡面,這一次的順序就是DAG的拓撲序。然後建邊就掃描原圖中的點就行了。

例題:CF949C,根據條件建有向邊縮點求最小的出度為0的強聯通分量

二、2-SAT

  1. 把每個點分成真假兩個狀態。
  2. x->y:若要取x這個狀態,必須取y這個狀態。
  3. 如果x->非x,那麼無解。
  4. 最後就縮點然後看每個點的哪個狀態在強連通分量內即可。
  5. a是真:非a->a

例題:P5332,每一個人在每一個時間建一個點然後2-SAT建圖,如果最後的那個x能夠連向最後的非x,那麼忽略這個點。在另外的點中找出每個人真能夠連向的所有真。

三、歐拉回路

  1. 有一個巧妙的方法。

例題:CF1361C

四、割點與橋

  1. 定義dfn和low兩個陣列。
  2. 點雙聯通分量是用割頂相連的,邊雙聯通是用橋相連的。
  3. 求點雙聯通,找到割點,從棧中彈出來的點都在同一個點雙連通分量中。
  4. 同理,邊雙和橋一樣。

例題:LCT維護動態的邊雙聯通縮點樹,查詢樹上路徑和。LCT經典維護方案,套一個並查集(Father),然後每個點訪問到之後直接訪問它的find(x),如果這個點是根,那相當於這個點存在在LCT中,否則不存在。複雜度沒有問題。

五、圓方樹

  1. 仙人掌:任意一條邊至多隻在一個簡單環內。
  2. 狹義圓方樹求解仙人掌問題。把仙人掌轉化為圓方樹從而可以使用樹形dp等問題求解。
  3. 廣義圓方樹對於每一個圖中的點雙連通分量建立一個方點,把原圖中的點刪掉然後從每一個方點向它所對應的點雙中的點連邊。兩個性質。

例題:CF487E,圓方樹樹剖板子。

六、網路流

  1. 最大流Dinic兩個優化:當前弧和炸點

例題:CF1082G,基礎網路流最小割模型建圖。

  1. dijk優化spfa的費用流,類似於Johnson。

  2. zkw費用流就是在最短路徑上跑Dinic。

例題TOPCODER12432

  1. 無源匯上下界可行流

  2. 有源匯上下界最大流