正睿NOI2020集訓 講課 Day1
上午
ZJOI2020 密碼
給定 \(p\) 級別在 \(10^{18}\) ,有一個未知數 \(x\) ,會給 \(a_ix\pmod p\) ,但有 \([-10^{16}/2,10^{16}/2]\) 的誤差。誤差之間獨立且隨機。\(x,a_i\) 隨機。
方法 1
一個條件相當於是 \(L_i\le a_ix\le R_i\) ,嘗試聯立兩個方程。
設 \(y=a_1x\) ,那麼推推推可以推出形為這樣的不等式:
\[L_1\le y\le R_1\\ L_2\le Ay\%p\le R_2 \]
魔改擴歐可以得到下面的最小整數解,然後???
把第一部分分塊,對於一塊 \(y\in [L_1,L_1+T-1]\)
在 \(err\) 較小(\(10^{11}\))的時候解不會太多,暴力判斷即可。
方法 2
考慮如果 \(a\) 較小,那麼 \(L_i\le a_ix\le R_i\) 這樣的方程的解可以被分成 \(a\) 段。
所以嘗試讓 \(a\) 變小。(???)
選 \(k\) 條方程,給每一個方程帶一個 \(\pm1\) 的係數,加起來。此時 \(err\) 的數量級不會變大(乘一個小常數?)。
所以可以選一些方程加起來,嘗試把 \(a\) 變小。
\([0,1]\) 內隨機 \(k\)
大力隨機即可獲得不錯的分數。
\(a\) 變小之後可以解出若干區間,然後多搞出幾個 \(a\) 就可以把很多組區間求交,然後就可以暴力了?
正解
上面減小 \(a_i\) 的嘗試有些類似於卡雜湊。
Tree Attack !
對於一個序列 \(\{a\}\) ,每次排序之後選相鄰的項的差,即可使得每次 \(n=n/2\) , \(\max a=\max a/n\) ,且每個 \(a\) 的係數都是 \(\pm 1\) 。
在這一題中 \(m\) 不夠大,但是係數也不一定必須是 \(0,\pm 1\)
還有 multi tree attack ……
ZJOI2020 序列
線性規劃
就是把一個數的貢獻分成兩部分,一個是連續的,一個是跳的,然後跳的最小操作次數也可以把奇偶分開做,所以就是線性規劃,轉一手對偶就做完了……
上面的圖略有一些筆誤,轉對偶之後是最大化 \(\sum_i (-a_i)u_i+\sum_i (a_i-a_{i-2})w_i\) 。
至於為什麼取值都是整數呢?操作一下轉成費用流即可證明。
怎麼轉成費用流?注意到 \(v_i,w_i\) 只在兩個不等式中出現,所以可以看做連點之間的邊;而 \(u\) 可以看做 \(S\) 連向點的邊或點連向 \(T\) 的邊。費用對應上去即可。
貪心
從左往右考慮。先考慮最左邊兩個。
可以發現,只要 \(a_1>0,a_2>0\) ,那麼必然有從 1 開始的連續減一線段,且長度至少為 2 。如果沒有那麼可以通過調整使得有。
到最後 \(a_1=0\) 或 \(a_2=0\) 。如果 \(a_1=0\) 那麼直接繼續,否則會有從 1 開始跳著減 1 。
然後考慮 2 和 3 ,我們想要用同樣的方法貪心,但是有一個問題:有一些操作可以連到 3 ,它們可以繼續往前連。
設連到 3 的有 \(A\) 個連續的, \(B\) 個跳的。先讓 \(A,B\) 都對 \(a_3\) 取 \(\min\) 。
如果 \(A+B\le a_3\) ,那麼容易發現把它們全部保留下來是最優的,然後情況和 \(a_1,a_2\) 一模一樣,照著做即可。
否則,設 \(k=A+B-a_3\) 為多餘的運算元,顯然有 \(k\le A,k\le B\) 。
多餘的看起來很不爽,所以令 \(A=A-k,B=B-k\) ,那麼 \(A,B\) 都要保留,並且還可以往前連 \(k\) 個免費的任意種類。
此時 \(A,B,a_3\) 都消失了,留給 \(a_2\) 的唯一方案是往前連跳的。
然後為了表現出 \(a_3\) 這裡有免費邊,把 \(a_3\) 置為 \(k\) ,答案減去 \(k\) 。
ZJOI2020 抽卡
我們先轉化題意。
先轉化題意。
這種隨機抽卡的題,可以考慮每一個沒有達成目標狀態的集合,同樣大小的集合走到的概率和期望呆在這的時間是一樣的,所以就轉化成了數每一個大小的不合法集合的個數。
然後考慮怎樣 dp 這個東西。可以設 \(dp_{i,j}\) 表示考慮了前 \(i\) 張牌,選了 \(j\) 張的方案數,然後轉移是 \(dp_{i,j}=dp_{i-1,j-1}+dp_{i-1,j}-[ok]\) 。其中 \([ok]\) 為 \(dp_{i-k-1,j-k}\) ,或在 \(i=k\) 時為 \(dp_{i-k,j-k}\) ,或前面不連續的時候是 0 。
對於 \(f_i=a\times f_{i-1}+b\times f_{i-k-1}\) 有 \(O(n/k)\) 的做法:其實就是看做走路,然後列舉 \(k+1\) 步的走了幾次,然後組合數算方案數即可。
容易看出上面的 dp 也是這樣的形式: \(dp_i=(x+1)dp_{i-1}-x^k dp_{i-k-1}\) 。
把式子列出來之後可能可以分治 NTT 。
式子(連續的一段,不連續的只需要最後分治乘起來就行了):
\[F_{m}=\sum_{i=0}^{\lfloor m /(k+1)\rfloor}\left(-x^{k}\right)^{i} (x+1)^{m-i(k+1)} \left(\begin{array}{c} m-i k \\ i \end{array}\right) \]
同樣是分治,本質上和上面那東西沒什麼區別。
好像 \(dp_{k,k}\) 被減掉的 1 還要額外做一遍?
PE437
顯然可以轉化為求 \(f_k=\sum [最長段\le k]\) 。
這東西顯然有 \(dp_i=n\times dp_{i-1}-(n-1)\times dp_{i-k-1}\) ,然後用 \(O(n/k)\) 算這個東西的方法就可以做了。
複雜度 \(O(n\log n)\) 。
EC Final 2019 J
顯然應該從小往大往裡面加數,考慮每個數能去哪裡。
序列裡面會有一些線段,表示線段裡面的數“基本”可以隨便移動。
加入一個數的時候,如果不在任何一個線段裡,那麼它顯然位置永遠不會變化,而是會帶來兩個新的線段(左右各一個)。如果線段相交了那麼會合並。
否則,它可以在已有的線段裡面移動,然後還可以把這個線段往兩邊擴充套件。注意不管怎麼擴充套件都不會覆蓋到確定動不了的點。
所以一個點加入的時候就可以確定它到底可以走到哪裡:原有的線段裡。而它的位置不能和別的點重合,所以方案數是 \(len-cnt\) ,其中 \(cnt\) 是之前就已經確定要在這個線段裡的點的個數。
下午
保序迴歸
要求:代價函式 \(f_i(x)\) 是凸的。
考慮
\[\sum_i f_i(x_i)=C+\sum_i\int_0^{x_i} f_i'(y)\mathrm{d}y=C+\int_0^{\infty}\sum_i [x_i\le y]f_i'(y)\mathrm{d}y \]
所以如果對於每個 \(y\) 用最小權閉合子圖求出 \(\sum_i [x_i\le y]f_i'(y)\) 的最小值,積分起來,就得到了答案的一個下界。至於為什麼能取到這個下界與函式凸性有關,不會證。
但是其實沒有必要這麼做,只需要整體二分一個 \(y\) ,跑最小權閉合子圖,就可以知道哪些點較小,哪些點較大,然後分治兩邊。分治的時候不在這個區間的點可以直接和 \(S\) 或 \(T\) 縮起來,保證複雜度。
要求整數的時候就是把求導改成差分。
保序迴歸
要求:代價函式是凸的。
對於每一個 \(\lambda\) ,看哪些點小於它,哪些大於它。如果大於它則貢獻是 \(f'_i(\lambda)\) 。跑最小權閉合子圖。
然後整體二分。
正確性感性理解。求出來的顯然是下界,至於為什麼取得到就不管了……
泡泡糖
在權值只能是 \(\{0,1\}\) 的時候可以輪廓線 DP 。
對於更大的情況基本上就是保序迴歸的整體二分思路。同樣不會證明正確性。
run
稱一個極長的週期串(週期 $\le $ \(|s|/2\) )為一個 run 。
一個字串的 runs 的個數是 \(O(n)\) 的。
怎麼求?……
本原平方串
可以被寫成 \(AA\) 的形式,且最小迴圈節恰好是 \(|s|/2\) 。
每個位置開頭的本原平方串的個數是 \(O(\log n)\) 的。
證明?……
ZJOI2020 字串
把一個串中一個平方串的第一次和最後一次出現稱為關鍵串。(不一定本原)
如 aabaabaabaabaabaaba
中的 aabaab
,abaaba
,baabaa
,aabaabaabaab
,...
-
關鍵串個數是 \(O(n\log n)\) 的。
-
詢問時答案“基本”是不同的關鍵串。
第一點的證明:
如果只迴圈兩次,那麼顯然是 \(O(n\log n)\) 的。
對於非本原的,掉線了……
可以和本原平方串對應起來?
一個串中本質不同平方串=本質不同關鍵串?
掉線快樂?
Another Chess Problem
看到這個圖可能會更明確一些:
發現這個題做過,就做完了 /fad
EC Final 2019 K
給了一個多邊形的三角剖分,邊有邊權,無向,求兩兩之間的最大流之和。
最大流轉最小割,然後轉成對偶圖最短路。
三角剖分圖的對偶圖是一棵樹(把外面無窮大平面拆成 \(n\) 個葉子)。
Gomory-Hu Tree 是兩兩最小割的最小生成樹。
此時的最小割是某兩個葉子的路徑長度。
考慮求出葉子組成的完全圖的最小生成樹。boruvka 或別的神仙東西。
可以發現如果把最小生成樹畫在圖上,不會相交(???)。
並且此時圖也有不錯的性質,可以求出 kruskal 重構樹(即“對偶”回去),就可以方便地求出兩個點的最小割了。
其實就是兩點的最小割就是找到能把它們分開的一對葉子,也就是路徑上的最小邊。
然而 dls 不記得怎麼處理相交的情況了,……
方法 2
同樣是轉成對偶圖。
考慮凸包上的邊權最小的邊,那麼如果有一個最短路走到了它旁邊的三角形對應的點,就一定會從這裡走出去。
所以可以把這條邊刪掉,合併它對應的葉子節點和三角形節點,然後把刪掉的邊權加到三角形的另外兩條邊上。此時那兩條邊變成了邊界上的邊。
如果這條邊刪掉之後刪透了,那麼就是得到了 gomory-hu tree 上面的一條邊。
怎麼實現?把刪邊的過程記下來,倒過來變成加邊,那麼就是合併兩個連通塊了。
EC Final 2019 B
一次走兩步,就比較好做了。
Junk Problem
如果是兩兩和不同,那麼可以構造這麼個集合: \(\{i\times 2p+i^2\%p\}\) 。
然後瞬間掉線……
對於異或,把高低位拆開,假設各有 \(n\) 位,那麼造一個 \(n\) 階不可約多項式 \(P(x)\) (於是有逆元(不過常數項為 0 也能有逆元?),有一些性質),然後低位隨便放,可以對應到一個 \(f(x)\) ,那麼高位就用 \(f^3(x)\pmod P\) (顯然也是模 2 意義下)。
考慮怎樣會相等。以下乘法都是模 \(P\) 模 2 的多項式乘法。
由於 \(a^3-b^3=(a-b)(a^2+ab+b^2)\) ,所以可以拆開一些東西。
然後因為是模 2 意義下,所以加減等價,所以證明相乘相等。
然後因為是個域(??),所以有唯一分解(??),就可以證明如果兩對東西相加相等則兩兩相等。
最後如果上界不是 \(2^{2n}-1\) 怎麼辦?
好像是取最近的那一邊亂搞。
由於模 \(P(x)\) ,所以一個非 0 多項式不管常數項是否為 0 都有逆元。
線上 O(1) 逆元
複雜度為 \(O(p^{2\over 3})-O(1)\) 。
設一個閾值 \(M\) ,對於一個 \(a\) ,如果能構造出 \(ak=h\pmod p\) ,那麼 \(a^{-1}=k\cdot h^{-1}\pmod p\) ,所以需要讓 \(h\) 較小。
掉線了……
Linear Matroid Parity
有很多對元素,一次要選一對,問最多選幾對使得還是擬陣。
可以理解為:有很多行向量被分成一對一對,一次選一對,選最多使得線性無關。
普通擬陣是 NP-Hard 。
掉線,跑路。
可以做 colorful spanning tree 和別的一些神奇東西。
……#%¥……
刪最少的點,使得剩下的圖是森林。
NP-Hard 。
如果度數小於等於 3 那麼是 P 。
先補成度數全部為 3 :……
掉線。