2019各省省選試題選作

2019各省省選試題選作

2019.05.09
把拖了幾天的SDOI Day2更了。姑且算是完結撒花?html

省份 Day1T1 Day1T2 Day1T3 Day2T1 Day2T2 Day2T3
ZJOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
HNOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
十二省 \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
GX/GZOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
BJOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
SNOI \(\surd\) \(\surd\) \(\surd\) \(\surd\)
JSOI \(\surd\) \(\surd\) \(\surd\) \(N/A\) \(N/A\) \(N/A\)
TJOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)
SDOI \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\) \(\surd\)

ZJOI

Day1T1 麻將

先考慮一個這樣的問題:給定一副麻將問其是否存在一個子集能胡。兩種牌型中七對子很好處理,只須要記有多少種數值出現了大於等於\(2\)次就好了。
考慮用\(dp\)去斷定是否能按第一種牌型胡。\(f_{i,0/1,j,k}\)表示從小往大考慮了\(1...i\)的面值,前面是否選了對子,選了\(j\)\(i-1,i,i+1\)順子,\(k\)\(i,i+1,i+2\)順子,最多能湊出的面子數(因爲\(i+1\)還沒有肯定,於是\(j,k\)並不會被計入面子數)。轉移時根據\(i+1\)的數量,枚舉\(i+1,i+2,i+3\)順子的數量,剩下的\(i+1\)組成刻子。
再考慮原題目中的權值指望怎麼轉化。顯然這個指望能夠拆成「在手上有\(i(i\ge13)\)張牌時檢查是否胡牌,若不胡則貢獻\(+1\)」,所以咱們考慮求出有\(i\)張牌時仍不胡的方案數,乘上\((4n-i)!\)後相加便可獲得總答案。
回到原問題。在原問題中咱們仍考慮按面值從小到大加入麻將牌,並將上述斷定胡牌的\(dp\)數組做爲狀態壓進當前\(dp\)中。經搜索發現本質不一樣的狀態只有\(S=3956\)種,本質不一樣的不胡狀態只有\(S_0=2091\)種,於是能夠設\(dp_{i,j,k}\)表示考慮\(1...i\)的面值,當前狀態爲\(j\),選了\(k\)張牌的方案數,轉移只要枚舉\(i+1\)面值選多少張,方案數乘個組合數便可。總複雜度爲\(O(n^2S_0)\)
code算法

Day1T2 線段樹

能夠發現操做的意義等價於,每次以\(\frac 12\)的機率進行一次區間覆蓋操做,求線段樹上有標記節點的指望個數。根據指望的線性性,只須要求出每一個節點有標記的機率\(f_i\)再求和便可。
爲了方便的維護這個機率,咱們須要額外對線段樹上每一個點維護該點到根的路徑上有標記的機率\(g_i\)。每次修改都會有\(O(\log n)\)個節點的\(f_i\)值變成\(\frac{f_i}{2}\)\(\frac{f_i+1}{2}\)\(\frac{f_i+g_i}{2}\)中的一種(請根據實際含義自行理解),而同時也會有\(O(\log n)\)棵線段樹子樹內的\(g_i\)值變成\(\frac{g_i+1}{2}\)
在具體實現中,能夠維護\(g_i'=1-g_i\),這樣對子樹內\(g_i'\)的修改就變成了\(g_i'\gets \frac{g_i'}{2}\),直接打區間乘法標記(或者直接記區間要除幾回\(2\))便可。
code數組

Day1T3 Minimax搜索

考慮對每一個\(R\)求出\(ans_R\)表示有多少個葉子集合知足權值\(\le R\),差分便可獲得答案。設樹上共有\(k\)個葉子節點,易知\(ans_n=2^k-1\)網絡

因爲咱們只須要改變\(w\)的值,而變成的值的可行域顯然是連續的,因此咱們只須要嘗試着將這個值改成\(w+1\)\(w-1\)便可。數據結構

若是可修改集合包含\(w\)那麼其權值必定爲\(1\)(只要把\(w\)改掉就萬事大吉了),所以\(ans_1=2^{k-1}\)函數

不然,若是想要把權值變成\(w+1\),那麼大於\(w\)的點的權值顯然不會被修改,而小於\(w\)的點的權值會被儘可能改爲\(w+1\)(若是修改代價不超過\(R\)的話)。把權值變成\(w-1\)的過程同理。能夠發現兩類修改互不影響,因此咱們只要分別求出兩類操做下\(w\)沒有被改變的方案數,直接相乘獲得的就是\(w\)沒有被改變的方案數。優化

\(f_i\)表示\(i\)點權值\(\le w\)的機率(設機率而非方案數能夠方便轉移),這樣奇數深度的轉移爲\(f_u=\prod f_v\),偶數層的轉移爲\(f_u=1-\prod(1-f_v)\)。同理,設\(g_i\)表示\(i\)點權值\(< w\)的機率,轉移與\(f\)的轉移徹底一致。注意在這裏\(f_i\)只考慮全部\(<w\)的葉子,\(g_i\)只考慮全部\(>w\)的葉子。spa

由此在\(R\)肯定的狀況下咱們能夠經過一遍樹形\(dp\)求出\(ans_R=2^{k-1}(1-f_1(1-g_1))+2^{k-1}\)。這樣咱們就獲得了一個\(O(n(R-L+1))\)的作法,能夠得到\(70\)分。code

滿分作法其實很顯然。\(R\)\(2\)\(n-1\)移動時每次只會改變至多兩個葉子的\(dp\)值,所以使用動態\(dp\)實現便可,複雜度\(O(n\log^2n)\),能夠得到\(100\)分。htm

在具體實現中,因爲深度奇偶性不一樣致使轉移不一樣,故能夠令\(f_i'=[\mbox{i點深度爲奇數}]f_i+[\mbox{i點深度爲偶數}](1-f_i)\),這樣轉移就能夠統一爲\(f_u'=\prod(1-f_v')\)

此外在動態\(dp\)的過程當中可能會出現乘\(0\)後除\(0\)的問題,須要開一個\(pair\)記錄\(dp\)值非零部分的乘積以及乘\(0\)的個數,從而實現信息可減。

code

Day2T1 開關

先求出\(n\)次操做後使開關狀態合法的方案數,其對應的指數型生成函數爲(記\(P=\sum_{i=1}^np_i\)\[F(x)=\prod_{i=1}^n\frac{e^{\frac{p_ix}{P}}+(-1)^{s_i}e^{-\frac{p_ix}{P}}}{2}\]

然而這個方案數包含了一些屢次達到合法狀態的方案,須要將其排除。考慮\(n\)次操做後回到原狀態的方案數對應的指數型生成函數:
\[G(x)=\prod_{i=1}^n\frac{e^{\frac{p_ix}{P}}+e^{-\frac{p_ix}{P}}}{2}\]

在具體實現中,只須要記錄\(F(x)=\sum_{i=-P}^Pa_ie^{\frac{ix}{P}}\)中的\(a_i\)係數便可,\(G(x)\)同理。這一部分暴力實現的話複雜度爲\(O(nP)\)

再記\(H(x)\)爲答案的生成函數,令\(F(x),G(x),H(x)\)對應的普通生成函數分別爲\(f(x),g(x),h(x)\),可知\(g(x)h(x)=f(x)\)

(本來這裏誤寫成了\(G(x)H(x)=F(x)\),實際上因爲答案是操做序列的一段前綴,所以\(g\)\(h\)的關係應當爲直接拼接而非組合相乘,對應的也應爲普通生成函數的乘法。感謝@leoiter指正。)

關於指數型生成函數與普通生成函數的轉化:當\(F(x)=\sum_{i=-P}^Pa_ie^{\frac{ix}{P}}\)時,\(f(x)=\sum_{i=-P}^P\frac{a_i}{1-\frac{ix}{P}}\)

此時要求的答案爲\(h'(1)\),使用公式\((\frac{f(x)}{g(x)})'=\frac{f'(x)g(x)-f(x)g'(x)}{g^2(x)}\)計算答案。可是\(x=1\)代入\(f(x)\)\(g(x)\)後函數不收斂。考慮將\(f(x)\)\(g(x)\)同乘上\(\prod_i(1-\frac{ix}{P})\)結果不變,此時\(f(x)=\sum_ia_i\prod_{j\neq i}(1-\frac{jx}{P})\),能夠計算出\(f(1)=a_P\prod_{i\neq P}(1-\frac{i}{P})\)\(f'(1)=-(\prod_{i\neq P}(1-\frac{i}{P}))(\sum_{i\neq P}\frac{a_i}{1-\frac{i}{P}}+a_P\sum_{i\neq P}\frac{\frac{i}{P}}{1-\frac{i}{P}})\)

(以上默認\(i,j\in[-P,P]\cap\mathbb{Z}\)

推導過程當中可能須要用到的東西:\((\prod_i(1+a_ix))'=\sum_ia_i\prod_{j\neq i}(1+a_jx)\)

\(g(x)\)的對應係數爲\(b_i\),不難發現實際上\(a_P=b_P=\frac{1}{2^n}\),於是能夠簡化一些運算,最終的答案爲\(2^n\sum_{i\neq P}\frac{b_i-a_i}{1-\frac{i}{P}}\)

code

Day2T2 語言

對每一個點求全部覆蓋該點的鏈的鏈並大小,加起來除以\(2\)就是答案。

樹上差分,即對於鏈\((x,y)\)\(x\)\(y\)處加入這兩個點,在\(fa_{lca(x,y)}\)處刪去(注意判出現次數)。線段樹合併便可,複雜度\(O(n\log n)\)

code

Day2T3 浙江省選

顯然每一個人就是一條直線。對全部人求個半平面交(簡易版,由於斜率均爲正),而後那些在半平面邊界上(包括一個整點)的人能夠拿第一名。

接着考慮剩下的人。若是剩下的某我的想要拿第二名,那麼他至少要在剩下的人中拿第一。對剩下的全部人作半平面交,獲得的就是全部第二名的候選人,接着拿全部第一名在這個半平面上二分求出他會讓哪段\(x\)座標範圍的名次\(+1\),即作一次區間覆蓋。當半平面邊界上的某人只被不超過\(1\)我的覆蓋時,他就能夠拿到第二名。

第三名至第\(m\)名依此類推,只須要作\(m\)次半平面交+二分便可,複雜度\(O(mn\log n)\)

實現上有些小細節,具體能夠參照代碼。code

HNOI

link

十二省聯考

Day1T1 異或糉子

把全部右端點丟到堆裏,每次取出最大的便可,須要實現可持久化\(Trie\)樹上求異或第\(k\)大。複雜度\(O(n\log a_i+k\log n+k\log a_i)\)
code

Day1T2 字符串問題

\(A_x\)向全部它支配的\(B_y\)連邊,而\(B_i\)向全部以它爲前綴的\(A_j\)連邊。上述方式建圖後,最終答案記爲圖中以\(A\)串長度爲權值的最長路。

直接暴力建邊的邊數是\(O(n^2)\)級別的,顯然難以承受。考慮優化這個建邊過程。

\(SAM\)後從上往下連邊就行啦,注意同一個節點內的全部串要按照長度排序(長度相同時\(B\)串要排在\(A\)串的前面)後串成一條鏈。這樣建圖的總點數不超過\(2n_a+n_b+SAM\)節點數。

此外:

數據千萬條,清空第一條。

多測不清空,爆零兩行淚。

code

Day1T3 騙分過樣例

我必定是閒得發慌纔去寫這種題的\(Q\omega Q\)
\(5\)個點是輸入\(x\)\(19^x\%p\)\(x\)的範圍比較大(超過long long的值域範圍)因此直接讀入字符串後十進制快速冪就好了。\(4,5\)兩個點須要本身猜模數。
\(6,7\)兩個點是爆int的錯誤示例。並不能快速冪,不過經過各類途徑能夠發現循環節不長,因此直接把循環節打出來就行了。
\(8,9,10\)是區間求質數。直接大力\(\mbox{Miller_Rabin}\)便可。
\(11,12,13\)是區間求\(\mu\)。能夠先分解三次根號\((10^6)\)範圍內的質因子,而後最多最會剩下\(2\)個質因子,先判斷是否相等(徹底平方數),再\(\mbox{Miller_Rabin}\)判斷其是不是質數便可。這部分跑得比較慢,所以面向數據卡了波常,代碼中全部難以理解的部分均爲卡常的跡象。
\(14,15,16\)區間求原根。設\(p-1\)\(k\)種不一樣質因子,那麼存在一種\(O(nk\log p)\)的判斷方法,同時也存在一種\(O(pk)\)的方法。二者結合就好了。
code

Day2T1 皮配

在沒有任何城市限制與偏好限制的狀況下,對一我的數爲\(s\)的學校定義其二元生成函數\(1+x^s+y^s+x^sy^s\)。將全部學校的生成函數\(\prod\)起來,因爲總人數已知,因此\(C_0,C_1,D_0,D_1\)等價於對\(x\)\(y\)的指數作了必定的範圍限制(在某個\([l,r]\)之間)。

對於一座沒有任何偏好的城市,設其學校人數集合爲\(S\),則其生成函數爲\((1+y^{sum(S)})\prod_{s\in S}(1+x^s)=\prod_{s\in S}(1+x^s)+y^{sum(S)}\prod_{s\in S}(1+x^s)\)。若存在一些學校存在偏好,則該學校對應在\(1\)\(y^{sum(S)}\)中的\(1\)\(x^s\)項要被刪去,而這並不會影響到其他沒有偏好的學校(由於對於其他的學校你仍能夠提一個\((1+x^s)\)項出去),而全部無關的項中\(x\)\(y\)相對獨立,因此能夠先分別\(O(nm)\)地計算沒有偏好的學校及城市的生成函數,再\(O(km^2)\)地暴力\(dp\)存在偏好的學校的生成函數。因爲限制了單所學校的人數上限,因此實際上覆雜度只有\(O(k^2ms_i)\)

code

Day2T2 春節十二響

根節點顯然自成一組,因此只須要考慮合併根的若干子樹。顯然最優策略會是:兩棵子樹內最大值分在一組,次大值分在一組......能夠經過數學概括證實必定不存在更優操做。

因爲須要支持動態插入(根節點),所以考慮使用堆來維護子樹內的決策。使用長鏈剖分,每次計算時先\(O(1)\)繼承長兒子,再暴力地合併其他兒子,複雜度能夠作到\(O(n\log n)\)

使用priority_queue::swap能夠作到\(O(1)\)交換兩個堆。

(其實std::swap複雜度也是\(O(1)\)的,感謝@EndSaH指正。)

code

Day2T3 但願

枚舉一個點,求全部救援隊都覆蓋其的方案數,但這樣顯然算重了,所以須要容斥。考慮一種方案下能被每一個救援隊都覆蓋的點必定是一個連通塊,其點數\(-\)邊數\(=1\),所以咱們只須要對每一個點求答案,再對每條邊求答案就好了。具體的,設\(f_{i,j}\)表示\(i\)點子樹中距離\(i\)不超過\(j\)的連通塊個數,\(g_{i,j}\)表示\(i\)點子樹外距離\(i\)不超過\(j\)的連通塊個數,轉移以下:
\[f_{i,j}=\prod_{v \in son(i)}(f_{v,j-1}+1)\]

\[g_{i,j}=g_{fa_i,j-1}\prod_{v\in son(fa_i)}(f_{v,j-2}+1)+1\]

這樣的時空複雜度均爲\(O(nL)\)code

考慮優化。
首先\(f\)的轉移能夠長鏈剖分。在長剖的過程當中,每當暴力合併一個輕兒子後,都須要將長鏈的一段後綴乘上一個定值,能夠轉爲前綴乘上其逆元,這樣暴力掃前綴複雜度纔是對的。因爲後綴乘上的值多是\(0\)不存在逆元,於是須要額外開兩個變量記錄一段後綴的值變成了多少。

\(g\)的轉移須要分輕重兒子分別考慮。首先能夠發現的是,若\(i\)點距離子樹內最深點長度爲\(d\),則\(g_i\)中只有狀態\(g_{i,L-d...L}\)是有用的,也就是說\(g_i\)須要保存的長度也只有\(i\)點子樹內最深深度那麼長。對於全部輕兒子,只須要記錄先後綴的信息便可,具體來講能夠對\(f\)實現可回退化,求\(g\)的時候倒着訪問全部兒子,這樣每次對\(f\)的操做回滾便可獲得前綴信息,同時邊作邊維護後綴信息便可。重兒子直接暴力掃一遍最終維護出的後綴信息便可,複雜度爲最長輕兒子長度。

因爲涉及到求逆元複雜度仍然是\(O(n\log mod)\),不過能夠發現每次須要求逆的東西都是某個\(f_{i,L}\),而這個東西能夠預處理\(dp\)一遍直接求出,於是能夠作到離線\(O(n)\)\(n\)個數的逆元。

講道理這道題難點不在算法而是在實現吧,相信你們應該都知道怎麼作,至於怎麼寫出來那就得各憑本事了呢。

code

GX/GZOI

Day1T1 與或和

拆位考慮,假設全部數字都是\(0/1\)。一個子矩陣與爲\(1\)當且僅當它全都是\(1\),或爲\(1\)當且僅當存在至少一個\(1\),反過來就是沒有\(1\)。所以求全\(1\)\(0\)子矩形個數就行了,複雜度\(O(n^2\log a_i)\)
code

Day1T2 寶牌一大堆

(出這種題有意思嗎)
反正大力\(dp\)就行了吧,相信你們對於麻將形式的\(dp\)已經很熟悉了。
題中給出的\(15\)\(18\)張牌的和牌方案,其實等價因而用一個槓子代替了一個面子,於是能夠統一爲一種\(dp\),即\(f_{i,j,k,x,y}\)表示考慮了前\(i\)種牌,有\(j\)\(i-1\)開頭的順子,\(k\)\(i\)開頭的順子,已經出現了\(x\)個面子/槓子和\(y\)個對子狀況下的最大分數,其中\(j,k\le2,x\le4,y\le1\)。此外就只剩下七對子和國士無雙兩個簡單\(dp\)了。
code

Day1T3 特技飛行

顯然強行二合一。第一問是給出平面上的若干點和\(k\)個關鍵點,每一個關鍵點有個覆蓋範圍\(r\),能夠覆蓋與其曼哈頓距離不超過\(r\)的全部點,求有多少個點會被至少一個關鍵點覆蓋。顯然曼哈頓轉切比雪夫(就是座標軸旋轉\(45^\circ\))後覆蓋範圍就是個矩形,所以排序+掃描線能夠作到\(\log n\)
第二問是求最多能夠作多少次擦肩而過,由於顯然若是每次都作對向交換的話是必定合法的。這其實等價因而問最少作多少次對向交換。考慮所有作擦肩而過後在終點處獲得的相對順序排列\(p\),每次的對向交換在最終的排列\(p\)上的做用體現即爲交換了某兩個元素的位置。由於咱們只須要用最小的交換次數將\(p\)還原成元排列便可。
code

Day2T1 逼死強迫症

\(f_{i,0/1/2}\),而後矩陣轉移便可。
code

Day2T2 旅行者

對每一個點求出到達這個點最近的關鍵點\(f_i\)以及從這個點出發能到達的最近關鍵點\(g_i\),而後枚舉一條邊\(u\to v\),若\(f_u\neq g_v\)則能夠用這條邊更新答案。
code

Day2T3 舊詞

權值差分後主席樹維護鏈並便可。固然也能夠離線線段樹作到空間線性。
code

BJOI

Day1T1 奧術神杖

權值轉對數後至關於求權值的平均值,所以使用分數規劃。對全部串創建\(AC\)自動機後\(dp\),複雜度\(O(ns\alpha\log\mbox{eps}^{-1})\),其中\(\alpha\)爲字符集大小,\(\mbox{eps}\)爲設定的精度範圍。
能過就好了。
code

Day1T2 勘破神機

第一個數列顯然就是\(f_1=1,f_2=2\)的斐波那契數列。第二個數列只有偶數項非零,單獨拿出來後有\(g_1=3,g_2=11,g_n=4g_{n-1}-g_{n-2}(n>2)\),能夠打表找規律或強行\(BM\)oeis大法好

顯然二者均爲線性常係數齊次遞推式,能夠根據其特徵根解得其通項式。通常的,設其特徵根爲\(x_1,x_2(x_1\neq x_2)\),則通項式爲\(f_n=c_1x_1^n+c_2x_2^n\)。特殊的,題中所給出的兩個數列的特徵根以及對應係數分別爲:
\[\begin{cases}x_1=\frac{1+\sqrt 5}{2}\\x_2=\frac{1-\sqrt5}{2}\\c_1=\frac{5+\sqrt 5}{10}\\c_2=\frac{5-\sqrt5}{10}\end{cases}\]
以及
\[\begin{cases}x_1=2+\sqrt3\\x_2=2-\sqrt3\\c_1=\frac{3+\sqrt3}{6}\\c_2=\frac{3-\sqrt3}{6}\end{cases}\]

接下來的推導均採用通常形式。
\(\binom nk\)能夠被認爲是一個關於\(n\)\(k\)次多項式,即\(\binom nk=\frac{1}{k!}\prod_{i=0}^{k-1}(n-i)\)
題目要求的是\(\sum_{i=1}^n\binom{f_i}{k}\),能夠轉化爲求\(\sum_{i=1}^nf_i^{1...k}\),於是只考慮怎麼求\(\sum_{i=1}^nf_i^k\)
\[\sum_{i=1}^nf_i^k=\sum_{i=1}^n(c_1x_1^i+c_2x_2^i)^k\\=\sum_{i=1}^n\sum_{j=0}^k\binom kj(c_1x_1^i)^j(c_2x_2^i)^{k-j}\\=\sum_{i=1}^n\sum_{j=0}^k\binom kjc_1^jc_2^{k-j}(x_1^jx_2^{k-j})^i\\=\sum_{j=0}^k\binom kjc_1^jc_2^{k-j}\sum_{i=1}^n(x_1^jx_2^{k-j})^i\]
後面是個等比數列求和,特判下\(q=1\)的狀況就行了。
總複雜度\(O(Tk^2\log n)\)。比較難受的一點是\(998244353\)下不存在\(3\)\(5\)的二次剩餘,於是須要擴域,即便用一個\(pair(a,b)\)來表示\(a+b\sqrt 3\),其中\(a,b\in\mathbb{R}\)
code

Day2T1 排兵佈陣

很顯然是個揹包,每次只枚舉有用的轉移點,暴力轉移便可。
code

Day2T2 光線

對於兩面鏡子\((a_1,b_1)\)\((a_2,b_2)\),考慮將其合爲一面鏡子\((\frac{a_1a_2}{1-b_1b_2},b_1+\frac{a_1^2b_2}{1-b_1b_2})\)
上面的式子其實很好推導,只須要枚舉光在兩鏡之間反射了多少次,便可獲得一個等比數列求和的形式,化簡後便可獲得上式。
把全部鏡子自下而上合併便可。
code

Day2T3 刪數

對於\(i\in[1,n]\),若數列中含有\(cnt_i\)\(i\),則進行對區間\([i-cnt_i+1,i]\)的區間覆蓋。最終的答案就是未被覆蓋部分的長度。
而後就只須要考慮如何維護這個東西了。區間覆蓋能夠認爲是區間\(+1\),計算答案時只須要數區間內最小值的個數便可(最小值不會小於\(0\))。因爲存在值域平移的操做,所以在線段樹中只維護真實值範圍在\([1,n]\)的區間覆蓋就好了。複雜度\(O(n+m\log n)\)
code

SNOI

Day1T1 字符串

\(n=10^6\)時倍增求後綴數組大約要\(0.6\sec\)。(雖然也能過就是了)

其實須要用到的只有相鄰兩個後綴的\(lcp\),直接\(O(n)\)從後往前預處理便可。

接着來就是一個std::stable_sort的事情了。
code

Day1T2 數論

\(x\to (x+P)\%Q\)會造成\(\gcd(P,Q)\)個長度爲\(\frac{Q}{\gcd(P,Q)}\)的環。

枚舉\(x\%P\)的值(即枚舉\(a_i\)),問題變成求有多少\(0\le x\le \lfloor\frac{T-1-a_i}{P}\rfloor\)知足\((Px+a_i)\%Q\in\{b_i\}\)。其實就是求從某個點出發走若干步(\(\lfloor\frac{T-1-a_i}{P}\rfloor\)步)能到達的全部點的點權和。隨便討論一下便可。複雜度\(O(P+Q)\)
code

Day1T3 通訊

費用流暴力建圖點數\(O(n)\)邊數\(O(n^2)\)
隨便分治一下能夠將點數和邊數都變成\(O(n\log n)\)級別。而後...就能跑了?
code

Day2T1 紙牌

恭喜SN喜題第三道麻將題!不知道下一道將花落誰家呢?

直接\(9\times9\)大力矩乘便可,複雜度\(O(9^3X\log n)\),固然其實也能夠作到\(O(9^2X\log n)\)
code

JSOI

T1 精準預測

如下用\((t,x)\)表示\(t\)時刻\(x\)這我的活着的狀態,\((t,\overline{x})\)表示\(t\)時刻\(x\)這我的死亡的狀態。

很顯然的\(\text{2-sat}\)建圖。對於第一種限制關係,連邊\((t,x)\to(t+1,\overline{y}),(t+1,y)\to(t,\overline{x})\)。對於第二種限制關係,連邊\((t,x)\to(t,\overline{y}),(t,y)\to(t,\overline{x})\)。此外還須要連邊\((t,\overline{x})\to(t+1,\overline{x}),(t+1,x)\to(t,x)\)

如此建圖後每一個\(i\)的答案即爲從\((T+1,i)\)出發不能到達的\((T+1,\overline{j})\)\(j\)的數量\((j\neq i)\)。固然還須要知足\(i,j\)二者有可能活下來,即\((T+1,i)\)沒法到達\((T+1,\overline{i})\)\((T+1,j)\)沒法到達\((T+1,\overline{j})\)

暴力建圖的點數爲\(2n(T+1)\)。首先能夠發現建出來的圖是一張\(\text{DAG}\),同時只有\(m\)條限制中被用到的點是有用的,其他不少點均只有一條連向上一時刻或者是下一時刻的出邊,能夠減少圖的規模至\(2m+2n\)固然這並非最優的,反正能過就好了。

問題轉化爲求\(\text{DAG}\)上每一個點出發能到達哪些關鍵點。這個問題目前只還能作到\(\text{bitset}\)複雜度,所以總時間複雜度\(O(\frac{nm}{\omega})\),看上去能過。

空間開不下?分屢次作不就行了嗎。

code

T2 神經網絡

姑且算是個二合一。

第一問是對每棵樹求出將這棵樹劃分紅\(1...n\)條鏈的方案數。注意在這裏鏈是有方向的,所以每選取一條長度大於\(1\)的鏈方案數就要乘\(2\)。這個能夠用\(O(n^2)\)的樹\(dp\)解決。

第二問是求將全部樹劃分的若干條鏈擺成一個環,要求相鄰不能同色(來自同一棵樹)的方案數。一個顯然的想法是容斥掉相鄰不一樣色,即強制若干對相鄰同色,容斥係數顯然應爲\(\pm1\)

先假設擺成的不是環而是鏈,即不考慮首尾不一樣色也不考慮循環同構。考慮用指數型生成函數分配序列上的位置。對於一棵\(n\)個節點的樹,設將其劃分紅\(i\)條鏈的方案數是\(f_i\),那麼其對應的指數型生成函數應爲:
\[\sum_{i=1}^nf_ii!\sum_{j=1}^i(-1)^{i-j}\binom{i-1}{i-j}\frac{x^j}{j!}\]

而後考慮怎麼拓展到環上。咱們欽定一種顏色(一棵樹)做爲環的開頭(即做爲第一個元素),若是這種顏色被分了\(i\)段,那麼這種方案在最終的答案裏就會被算\(i\)次。所以咱們將這種顏色的指數型生成函數設爲:
\[\sum_{i=1}^nf_i(i-1)!\sum_{j=1}^i(-1)^{i-j}\binom{i-1}{i-j}\frac{x^{j-1}}{(j-1)!}\]
然而這樣沒有考慮首尾不一樣色。不過咱們只須要減去強制首尾同色的方案就行了:
\[\sum_{i=2}^nf_i(i-1)!\sum_{j=2}^i(-1)^{i-j}\binom{i-1}{i-j}\frac{x^{j-2}}{(j-2)!}\]
上下兩個函數作差後獲得的就是這種被欽定的顏色對應的指數型生成函數。

把全部函數(暴力地)捲起來便可獲得答案。

code

T3 節日慶典

一個位置做爲最小循環表示的起始位置的一個必要條件爲以其爲起始位置的後綴是一個最小後綴。若是作過這個題的話應該知道一個字符串的最小後綴只有至多\(\log n\)個,因此暴力維護出這個備選集合再比較就好了。

簡單證一下這個性質:考慮相鄰的兩個最小後綴\(i,j\),若\(|j|<|i|<2|j|\),則說明\(i=AAB,j=AB\),其中\(A,B\)均爲字符串,且\(B\)\(A\)的一個嚴格前綴。此時考慮\(i=AAB,j=AB,k=B\),能夠發現不管如何最小後綴都會在\(i\)\(k\)之間產生,\(j\)不可能成爲最小後綴,由此說明相鄰兩個最小後綴之間必定至少相差\(1\)倍,所以數量不超過\(\log n\)

然而\(n\)的規模大得有些超越想象,傳統後綴數據結構可能難以勝任。能夠考慮退而求其次,在\(O(n)\)的時間複雜度內求出原串的全部後綴與原串的\(lcp\)長度,即便用所謂的\(\text{Z-algorithm}\)。因爲備選集合內的後綴必定存在前綴關係(較短串必定是較長串的前綴),所以比較時須要用到的也就只有每一個後綴與原串的\(lcp\)了。

code

TJOI

Day1T1 甲苯先生的字符串

矩乘便可。
code

Day1T2 甲苯先生的滾榜

動態開點線段樹+樹狀數組維護便可。
code

Day1T3 唱、跳、rap 和籃球

因爲非法串不可能相交,因此能夠直接枚舉非法串至少出現多少次,剩下位置隨便填,容斥便可獲得答案。設出現非法串出現至少\(i\)次的方案數是\(dp_i\),則答案爲\(\sum_{i=0}^{min\{n/4,a,b,c,d\}}(-1)^i\binom{n-3i}{i}dp_i\)

考慮求\(dp_i\)。方案數顯然就是四個指數型生成函數捲起來,即\(dp_i=[\frac{x^{n-4i}}{(n-4i)!}](\sum_{i=0}^{a-i}\frac{x^i}{i!})(\sum_{i=0}^{b-i}\frac{x^i}{i!})(\sum_{i=0}^{c-i}\frac{x^i}{i!})(\sum_{i=0}^{d-i}\frac{x^i}{i!})\)。暴力計算複雜度\(O(n^3)\),能夠考慮維護前兩個函數的乘積與後兩個函數的乘積,每次\(i\)改變時只須要\(O(n)\)便可修改兩個多項式,求多項式的某一項係數也能夠直接\(O(n)\),總複雜度\(O(n^2)\)
code

Day2T1 大中鋒的遊樂場

設狀態\((u,x\in[-k,k])\),最短路便可。
code

Day2T2 甲苯先生和大中鋒的字符串

\(\text{SAM}\)便可。
code

Day2T3 甲苯先生的線段樹

先求出路徑上全部點編號和\(n\)。設路徑深度最小的點爲\(x\)

\(x\)爲中點,枚舉左右兩側鏈的長度\(L,R\)\(L,R\)可能爲\(0\))。顯然在肯定了\(n\)\(L,R\)後,\(x\)也惟一肯定了,由於在\(L,R\)已知的前提下,\(x\)的不一樣取值對應的\(n\)的可行範圍是無交的。因爲\(x\)是肯定的,因此咱們能夠把問題規約到\(x=1\)的狀況上來。

對於\(x=1\),咱們只須要安排一下左右兩棵子樹長成什麼樣便可。首先\(n\)的取值下界是\(2^{L+1}+3\times 2^R-4\),以後每當在深度爲\(d\)處選擇了右子樹進入,就會給\(n\)值加上\(\sum_{i=0}^d2^i=2^{d+1}-1\)的貢獻。這個問題等價於咱們要安排兩個長度分別爲\(L-1\)\(R-1\)\(01\)串,其第\(i\)位(\(0\)下標)的位值爲\(2^{i+1}-1\),使得這兩個字符串的總權值加上\(n\)的取值下界後恰等於\(n\),求安排兩個\(01\)串的方案數。這個問題直接數位\(dp\)便可(或者像我同樣懶直接寫記搜)。

對於\(x\neq 1\),此時\(n\)的取值下界是\((2^{L+1}+2^{R+1}-3)x+2^R-1\),令\(k=(2^{L+1}+2^{R+1}-3),b=2^R-1\),此時\(x\)的取值必定爲\(\lfloor\frac{n-b}{k}\rfloor\),因而即可以規約爲\(n'=(n-b)\%k,x=1\)的問題。

總複雜度大概是\(O(\log^4n)\)\(O(\log^5n)\)

code

SDOI

Day1T1 快速查詢

維護全局標記\((a,b)\)表示維護的數\(x\)的實際值爲\(ax+b\),這裏須要始終保證\(a\neq 0\),初始時\(a=1,b=0\)
單點修改爲\(val\)就把維護的值改爲\(\frac{val-b}{a}\)。注意須要逆元須要實時維護。
加法直接加。
乘法若\(val\neq 0\)就直接乘,注意加法標記也要乘。不然操做就是所有賦值爲\(0\)
賦值爲\(val\)就把維護的數組所有清零,而後令\(a=1,b=val\)。顯然清零的複雜度不會超過單點修改的複雜度。
查詢直接查。
總時間複雜度\(O(q\log p+tq)\)

code

Day1T2 染色

首先有個很顯然的沒分裸暴力,記\(f_{i,j,k}\)表示\(dp\)到第\(i\)列,這一列的兩個格子的顏色分別是\(j,k\)的方案數,轉移顯然。

考慮子任務\(1,2\)。稱包含已染色格子的列爲關鍵列,咱們只須要考慮關鍵列之間的轉移便可。因爲關鍵列有一種顏色已經肯定,因此\(dp\)狀態中就只須要記另一個格子的顏色便可,這樣的狀態數就只有\(O(nc)\)了。轉移時枚舉當前格子的顏色,能夠作到\(O(1)\)轉移。

在這裏須要求出這些東西的方案數(假設中間\(0\)的列數爲\(z\)):

\(\begin{pmatrix}x&0&\cdots&0&x\\y&0&\cdots&0&y\end{pmatrix}\)
\(\begin{pmatrix}x&0&\cdots&0&y\\y&0&\cdots&0&x\end{pmatrix}\)
\(\begin{pmatrix}x&0&\cdots&0&x\\y&0&\cdots&0&w\end{pmatrix}\),它等價於\(\begin{pmatrix}x&0&\cdots&0&w\\y&0&\cdots&0&y\end{pmatrix}\)
\(\begin{pmatrix}x&0&\cdots&0&y\\y&0&\cdots&0&w\end{pmatrix}\),它等價於\(\begin{pmatrix}x&0&\cdots&0&w\\y&0&\cdots&0&x\end{pmatrix}\)
\(\begin{pmatrix}x&0&\cdots&0&w_1\\y&0&\cdots&0&w_2\end{pmatrix}\)

\(g_{z,0/1/2/3/4}\)分別表示上述五種狀況下給中間的\(0\)染色的合法方案數。(代碼中\(g_z\)記的是\(z-1\)\(0\)的方案數)

轉移有點小複雜能夠參考代碼。

求出\(g_z\)以後就能夠愉快地\(dp\)了。每遇到一個關鍵列就大力討論轉移,複雜度\(O(nc)\)

對於子任務\(3,4\)中存在的兩個格子均已染色的列,稱其爲分割列,能夠發現分割列兩側的方案數獨立,所以須要實現分割列到關鍵列、關鍵列到分割列的轉移,分割列到分割列之間直接討論一下顏色是否相同乘上方案數就好了。

\(O(nc)\)地實現了上述內容便可得到\(96\)分的好成績。發現咱們對與維護的\(dp\)數組作的全部操做均爲前一道題中的操做,所以Ctrl-C Ctrl-V再隨便改改便可經過此題。

96分code
100分code

Day1T3 世界地圖

對每一個前綴\(i\)維護出前\(i\)列的\(\text{MST}\)將第一列和第\(i\)列的點設爲關鍵點的虛樹,虛樹邊權爲原樹的路徑最大值。合併的時候只須要對這個\(O(n)\)級別的虛樹作一次最小生成樹就好了。複雜度\(O(n(m+q)\log n)\)

code

Day2T1 熱鬧的聚會與尷尬的聚會

考慮以下構造方法:每次從圖中選取一個度數最小的點,將其以及與其相鄰的點刪去。設該操做一共進行了\(q\)次,第\(i\)次選取了點\(a_i\),刪除了包含點\(a_i\)在內的共\(b_i\)個點,假設\(b_t\)\(\{b_i\}\)的最大值,那麼能夠選取在第\(t\)次及之後刪除的點做爲\(P\)集合(即熱鬧的舞會),選取\(\{a_i\}\)做爲\(Q\)集合(即尷尬的舞會)。

不難發現\(Q\)必定是一個獨立集,且\(|Q|=q\)\(\sum_{i=1}^qb_i=n\)\(P\)集合此時的\(p\)值剛好爲\(b_t-1\)。顯然\((p+1)b_t\ge n+1\),所以這種構造方法是可行的。

用智障的方法維護度數最小的點,複雜度\(O(Tm\log n)\)
code

Day2T2 移動金幣

階梯博弈。只有奇數層的石子有用,所以只須要考慮奇數層,偶數層用組合數分配便可。

後手必勝當且僅當奇數層石子數異或和爲\(0\),也就是說每一個二進制位的\(1\)的個數都是偶數。搞\(\log n\)個只有\(\frac{\frac{m+1}{2}}{2}+1\)項有值的多項式(暴力地)乘起來就行了,複雜度\(O(nm\log n)\)

code

Day2T3連續子序列

\(\text{Thue-Morse}\)序列有許多許多優美的性質(因此這題感到無從下手?)能夠參考A010060

這裏咱們用到其中一條有趣的性質:\(\text{Thue-Morse}\)序列的另外一種生成方式。

考慮先令\(T.M.=\{0\}\),隨後每次用\(01\)替換原序列中的\(0\),用\(10\)替換原序列中的\(1\),每次替換後序列長度翻倍,由此反覆操做便可獲得\(\text{Thue-Morse}\)序列,且每次操做後都可以獲得一個其長度爲\(2^k\)的前綴。

這種構造方法基於\(0\to01,1\to10\),能夠將這個過程反過來,即\(1\gets 01,0\gets 10\),能夠發現這個操做就是把字符兩兩劃分紅組後映射爲\(0/1\)。注意對於任意一個給定的長度大於\(2\)的串\(s\),其均有兩種劃分方案,固然若是某種劃分方案中存在一組兩個字符相同,那麼這種劃分就是不合法的。

所以咱們只須要考慮對串\(s+k\)(表示在串\(s\)後面加上\(k\)個字符)進行上述的操做便可。因爲每次\(|s|\)\(k\)都會減少一半,於是使用記憶化搜索的總狀態數爲對數級。注意要對一些遞歸邊界進行特判。
code

相關文章
相關標籤/搜索