這個題訓練的時候做了,結果只有兩個人過,而且還有一個寫的是狀壓DP……
令 \(dp_{n,d}\) 表示n個點,最大深度為d的二叉樹個數.
轉移分為兩種情況:
1、1號節點只有1個子樹。此時的DP值為 \(dp_{n-1,d-1}.\)
2、1號節點有多於一個子樹。由於2號節點的父親一定是1,我們考慮枚舉2號節點所在子樹的大小和最大深度然后暴力轉移,復雜度\(\Theta(N^4).\)
精細實現應該可以做到 \(\Theta(N^3).\)
至於求答案下取整的問題,可以考慮使用long double
或__int128.
代碼見 : my solution
這個題訓練的時候做了……然后……我圓方樹對方點兒子排序的部分寫錯了……
建出圓方樹,然后考慮DP.
對於每個方點x
,我們需要知道兒子節點(圓點)還剩下度數為0/1/2
的方案數,用來DP。
對於每個圓點x
,我們需要知道兒子節點會用掉x
的多少度數以及對應的方案數,不難想到把它們寫成一個多項式,卷積起來即可得到。這個點還剩下度數為0/1/2
的方案數。
觀察到不管是圓點還是方點,會用掉父親節點的度數一定 \(\leq 2\) ,所以直接分治FFT,復雜度不超過 \(\Theta(n\log^2 n)\)
代碼見 : my solution
考慮 \(dp_{i,a,b,0/1}\) 表示當前DP到第i個,目前有a個黑色的奇數點,b個白色的計數點的方案數,轉移直接暴力即可。
可以發現狀態里的a/b
的值實際上沒意義,如果沒有,那么顯然當前點必然是奇數;如果有,那么就是 \(\frac{1}{2}\) 的情況用偶數轉移, \(\frac{1}{2}\) 的情況用奇數轉移即可.
\(\Theta(n).\)
代碼見 : my solution
解法1:
考慮分治解決這個問題。
維護當前的合法區間,如果擴展區間不會讓 \(\texttt{gcd}\) 變小的話就直接擴展。
然后考慮往兩邊走即可。
左右各做一遍,然后取max即可。
\(\Theta(n\log n \log A_i)\)
解法2:
對於同一個\(L\),gcd只有\(\log(A_i)\)種,那么對\(R\)記錄這\(\log\)個區間即可.
\(\Theta(n\log^2 A_i)\)
在並查集上維護每個聯通塊的直徑,同時用 \(LCT\) 維護樹形態即可。
\(\Theta((n+m)\log n)\)
代碼見 : my solution
首先,材料的前兩個屬性可以唯一確定一個材料,合金的前兩個樹形也可以唯一確定一個材料。
那么材料和合金都可以被看成平面上的點 \((a_i,b_i)\) 或 \((d_i,e_i)\)
不難發現,一些材料能表示出一種合金當且僅當這個合金(在平面上的點)在選取的材料(在平面上的點)組成的凸包內。
不難發現,選取的點凸包上的邊一定滿足:所有的合金代表的點都在這條邊的某一側,或者在這條線段上(不是直線上)
那么我們直接求個最小環就行了。
復雜度 \(\Theta(n^3+mn^2).\)
注意特判答案為 1 或 2 的情況。
代碼見 : my solution
直接線段樹上打 \(tag\) 即可,如果遇到打tag之后存在不同的值的區間,那么就往下遞歸。
復雜度分析 :
記一個節點的勢能 \(f(node) = \sum\limits_{i=0}^{31} g(node,i)\) ,其中 \(g(node,i)\) 表示 \(node\) 節點內部的所有數字中,第 \(i\) 個二進制位上是(1)/否(0)有不同的值。
一開始勢能是 \(\Theta(n\log n \times 31)\) 的。
每次修改最多增加 \(\Theta(\log n \times 31)\) 的勢能,過程中如果暴力遞歸了一次那么勢能必然也會減去1,所以復雜度為 \(\Theta((n+m) \log n \times 31).\)
代碼見 : my solution
LOJ#6513. 「雅禮集訓 2018 Day10」足球大戰
首先判掉 \(p=0/1\) 或者 \(q=0/1\) 的情況。
記 \(x = \frac{p}{1-p}\) , \(y = \frac{q}{1-q}\) ,不難發現主場進 \(i\) 個球的概率為 \(\binom{n}{i} \times x^i\) , 客場進 \(i\) 個球的概率為 \(\binom{n}{i} \times y^i\)
那么直接計算概率就可以了。
實現的時候,由於空間是 \(64MB\) 所以我們只能開一個 \(O(n)\) 的數組。
可以發現我們只需要預處理階乘的逆元。
實現要注意常數和空間。
代碼見 : my solution
不難發現題目要求一個不定根的最小樹形圖。
那么直接套板子即可。
\(\Theta((n+m)\log n)\)
代碼見 : my solution
LOJ#6501. 「雅禮集訓 2018 Day4」Cube
答案為 \(\binom{n}{m} \times 2^{n-m}\)
證明1 :
考慮枚舉\(m\)維作為超立方體,令剩余的\(n-m\)維在\(0/1\)中任意選擇,方案即為選出\(m\)維的方案和\(n-m\)維選擇\(0/1\)的方案的乘積即\(\binom{n}{m} \times 2^{n-m}\)
證明2 :
首先 \(f_{1,1} = 1,f_{1,x(x>1)} = 0.\)
對於 \(f_{n(n>1),m}\) ,我們嘗試尋找其遞推式。
不難發現我們要么是當前一維拿來確定,即在兩個\(n-1\)維超立方體中找出\(m-1\)維超立方體的方案數,為 \(f_{n-1,m-1}\) .
或者我們直接遞歸到兩個子超立方體中,此時的答案為 \(2f_{n-1,m}\) .
不難發現答案即為 \([x^m](x+2)^n = \binom{n}{m} \times 2^{n-m}\) .
代碼見 : my solution
LOJ#6502. 「雅禮集訓 2018 Day4」Divide
考慮把數列\(w_i\)重新排列,使得新數列 \(w_i\) 滿足對於任意 i , 所有的 \(w_{j(j<i)} + w_i \geq m\) 或者所有的 \(w_{j(j<i)} + w_i < m\) ,然后 \(O(n^2) DP\) 就容易了。
如何構造?
先把 \(w_i\) 從小到大排序。一開始答案序列 \(ans\) 為空。
如果 \(w_1+w_n \geq m\) ,那么對於所有 \(w_{i(i<n)},w_{i(i<n)}+w_n \geq m\) ,可以把 \(w_n\) 放到 \(ans\) 的末尾,並刪去 \(w_n\)
否則,對於所有 \(w_{i(i<n)},w_{i(i<n)}+w_n < m\) ,可以把 \(w_1\) 放到 \(ans\) 的末尾,並刪去 \(w_1\)
那么就可以 \(\Theta(n\log n)\) 構造了。
復雜度 \(\Theta(n^2)\)
代碼見 : my solution
不難發現,一條父親到左兒子的邊相當於一個\(\texttt{<}\)限制,一條父親到右兒子的邊相當於一個\(\texttt>\)限制。
考慮用樹鏈剖分維護這些限制,2操作直接線段樹上打tag,把\(\texttt<\)限制和\(\texttt>\)限制交換一下即可。
\(\Theta(n\log^2 n)\)
代碼見 : my solution
考慮分塊,設塊大小為\(S\)。每個塊用一個bitset記錄塊中顏色,整塊之間打st表,查詢的時候整塊st表查,零散部分暴力即可。
時間復雜度\(\Theta(\frac{nS\log S}{w}) - \Theta(\frac{n}{w}+S)\)
空間復雜度\(\Theta(n+\frac{nS\log S}{w})\)
代碼見 : my solution
LOJ#6503. 「雅禮集訓 2018 Day4」Magic
對每個 \(a_i,\) 建出一個多項式 \(F(x) = \sum\limits_{j=1}^{a_i} x^j \binom{a_i-1}{j-1},\) \(j\)次項系數表示這些卡牌被分成\(j\)段的方案數,也表示它們有\(a_i-j\)處強制為魔術對的方案數。
對它們進行\(EGF\)卷積,最后的結果\(G(x)\)的\(n-i\)次項系數 \([x^{n-i}]G(x)\) 即為強制有\(i\)處為魔術對的方案數。
最后二項式反演即可得到答案為 \(ans = \sum\limits_{i=k}^{n} (-1)^{i-k} \binom{i}{k} [x^{n-i}]G(x).\)
怎么求出把\(m\)個長度之和\(=n\)的多項式的卷積的結果呢?
用一個堆記錄當前多項式,每次找長度最短的那兩個卷積起來即可,可以證明復雜度不超過\(\Theta (n\log^2 n)\)
代碼見 : my solution
首先把兩個過程分別貪心,然后對應匹配一下即可。
\(\Theta(l \log n).\)
代碼見 : my solution
一個 \(R \times C\) 的棋盤,你有 \(Q\) 組詢問,每次詢問國王走 \(R-1\) 步從 \((1,x)\) 到達 \((R,y)\) 有多少種方案。你只需要輸出答案對 \(998244353\) 取模的結果。
首先不難有一個每組詢問\(\Theta(C^3 \log R)\)的做法,即設轉移矩陣 \(T\) 滿足 \(T[i][j] = [ |i-j| \leq 1 ],\)然后矩陣快速冪。
因為轉移是向量乘矩陣的形式,所以在\(C\)固定的情況下,對於任意的\(x,y,\)答案都是一個關於\(R\)的線性遞推,並且有相同的特征多項式。
\(T\)的特征多項式\(f(\lambda)\)為\(det(\lambda I - T),\)即我們需要求如下矩陣的行列式:
\( \begin{bmatrix} \lambda - 1 & -1 & & \\ -1 & \lambda - 1 & -1 & \\ & -1 & \lambda - 1 & \ddots \\ & & -1 & \ddots \\ \end{bmatrix}\)
不難發現行列式/特征多項式滿足遞推式 : \(F_C = (\lambda - 1)F_{C-1} - F_{C-2}\)
可以通過矩陣乘法在\(\Theta(\log C)\)的時間內求出\(F_C\)的一個點值,那么求出所有單位根的點值然后再\(IDFT,\)就可以在\(\Theta(C\log C)\)的時間內獲得\(F_C\)的系數了。
記\(x^R\)對特征多項式\(F_C\)取模之后的每一項系數為\(r_0,r_1,..r_{C-1},\)那么\(ans_R = \sum\limits_{i=0}^{C-1} ans_i \times r_i.\)
考慮翻折容斥,因為\(i<C,\)所以上下界不會同時越界,因此可以把有邊界的\(ans\)轉化成\(3\)個無邊界的查詢。
對於無邊界的情況,我們要求\(\sum\limits_{i=0}^{C-1} r_i (x^{-1} + x^0 + x^1)^i,\)分治\(FFT\)即可。
然后就可以\(\Theta(1)\)查詢了。
\(\Theta(C\log C \log R) - \Theta(1).\)
代碼見 : my solution
首先把價值取反,然后問題轉換為求最大權值。
考慮一個最小割模型:
S連向葯,容量INF+權值,割掉這條邊相當於不選這個葯;
葯連向葯材,容量INF;
葯材連向T,容量INF,割掉這條邊相當於選這個葯材;
不難發現在最小割方案中,割掉葯連向葯材的邊是不優的。
因為有完美匹配,所以對於任意左部點集合 \(S\) , \(|N(S)| \geq |S|,\) 因此至少會割掉\(n\)條邊。
又因為邊權加上了 \(INF\) ,所以不會割掉 \(>n\) 條邊。
因此不選的葯的個數 + 選的葯材個數 = n,所以可以得到選的葯材個數 = 選的葯的個數。
然后跑一個最小割即可。
\(O(Dinic(n,n^2))\)
代碼見 : my solution
雙倍經驗 : CF103E Buying Sets
直接線段樹套\(Trie\)即可。
\(\Theta(n\log n \log a_i).\)
代碼見 : my solution
IOI2020Day1T2 連接擎天樹
IOI2020題解-洛谷博客 IOI2020題解-cnblogs
首先,如果存在 \(p_{i,j}=0\) ,那么就分成了多個聯通塊,這些聯通塊分開做即可。
由於 $p_{i,j} \leq 3 $ 所以一個聯通塊當中不能出現多於一個環,否則必然會有兩個點之間有 \(4\) 條路徑。
沒有環的情況(聯通塊內 \(p_{i,j}\) 均為 \(1\) )先判掉,那么這個聯通塊正好有一個環。
不難發現,如果兩個點 \(x\) 和 \(y\) 之間的路徑需要經過多於一個環上的節點,那么 \(p_{x,y}\) 就等於 \(2\) ,否則 \(p_{x,y}\) 為 \(1\) , 因此如果存在 \(p_{x,y} = 3\) 那么也無解。
把所有的 \(p_{x,y} = 1\) 的 \(x\) 和 \(y\) 合並到一個聯通塊中,把這些塊之間連成一個環, \(check\) 是否合法即可。
\(\Theta (n^2)\)
code見我的題解 solution-洛谷博客 solution-cnblogs
IOI2020Day1T3 嘉年華獎券
IOI2020題解-洛谷博客 IOI2020題解-cnblogs
首先我們考慮如何求出最大值。
不難發現這個抽獎的過程中,工作人員必然會取中位數來最小化當前輪次的獎勵。
因為n是偶數,不難發現我們能獲得的獎勵為:
設當前輪次使用的獎券上的數值為 \(a_{1,2...n}\) 並且已經從小到大排序,那么
\(\large ans=\sum\limits_{\frac{n}{2}+1\leq i\leq n} a_i -\sum\limits_{1\leq i\leq \frac{n}{2}} a_i\)
也就是說,有 \(\large \frac{n}{2}\) 個數對答案的貢獻為 \(a_i\) ,另 \(\large \frac{n}{2}\) 個數對答案的貢獻為 \(-a_i\) , 並且所有負貢獻的數字都不大於正貢獻的數字。
可以發現,經過 \(k\) 次過程獲得的最大值,相當於我們在 \(n\) 種顏色的獎券上的數字中,每種顏色選取 \(k\) 個數字,並在其中選 \(\large \frac{nk}{2}\) 個數字,使其對答案的貢獻為正數 ,令另外一半的數字的貢獻為負數 ,然后求和即為答案。
不難發現如果我們獲得了這個取數問題的最優解,那么必然存在一種方案把這 \(nk\) 個數分成 \(k\) 組使得每組中有 \(n\) 個顏色兩兩不同的數,一半取負貢獻,一半取正貢獻,並且負貢獻的數都不大於正貢獻的數字。即有對應原問題的合法方案。
證明:如果不存在合法方案,那么對於任何一種方案,必然存在同一組數字中有一個取負貢獻的數大於一個取正貢獻的數。這時候交換一下它們的符號就可以獲得一個更優的解,所以如果取得了最優解的取數方案,必然有一個對應了原問題的合法方案。
取數問題的貪心:先默認都取負數,然后再貪心的做 \(\large \frac{nk}{2}\) 次把負數換成正數的操作即可。
然后我們考慮如何構造方案。
遞歸構造,考慮從當前的 \(nk\) 個數字中取出 \(n\) 個顏色兩兩不同的成為一組,保證它合法后再對剩下的 \(n(k-1)\) 個數字繼續構造。
從每種顏色中取出一個最大的正數和一個最小的負數並將正數和負數分別排序,枚舉正數和負數之間的邊界,\(two-pointers\) 的同時維護可用的正/負數數目即可。
因為正數和負數分別取到了最大和最小,所以在整個取數問題有對應方案的時候這個子問題必然能找到一組解,可以繼續遞歸。
由於遞歸的時候保證了選數方案一直是當前的最優解,所以一直都能保證當前的選數方案有一組對應原問題的解。
\(\Theta(nm\log n)\)
code見我的題解 solution-洛谷博客solution-cnblogs
首先考慮一個 \(\Theta(nm)\) 的暴力。
一次操作對差分數組的影響是把兩個距離相差k的位置都異或上1,那么我們只需要保證對於模 k 的每個余數的位置上的1的總數為偶數即可,並且答案為相鄰兩個的位置差的和 / k。
那么對於每組詢問,我們只需要做一個差分即可。判斷是否有解可以考慮哈希。需要注意細節。
\(\Theta(n+m+k)\)
代碼見 : my solution
IOI2020Day1T1 植物比較
IOI2020題解-洛谷博客 IOI2020題解-cnblogs
首先我們考慮構造出一個符合題意的數列。
每次選擇一個 前面 \(k-1\) 個位置上都是 \(0\) 或者已經選過,並且當前位置為 \(0\) 的位置,然后把它的值置為這個序列的最大值。不難發現這樣做一定能構造出一個符合要求的排列。
這個構造的過程可以用線段樹+set優化到 \(\Theta(n\log n)\)
不難發現,一個排列符合條件相當於它的每連續 \(k\) 位的相對大小關系和我們構造出來的排列相同。
那么,不難證明在 \(2k>n\) 的時候只有唯一的一個排列,所以不判 \(0\) 直接比較可以獲得子任務 \(2/3/4\) 的分數。
現在排列不唯一怎么辦?
考慮對於每個點,求出它往左/右 \(k\) 個位置中,比他小的最大的數字的位置,分別記為 \(pre_i\) 和 \(nxt_i\) ,然后對 \(pre/nxt\) 做一個倍增。
對於每組詢問,假定我們構造的排列 \(A\) 滿足 \(A_x>A_y\) 。
我們從 \(x\) 開始,通過 \(nxt\) 和 \(pre\) 往左右跳,保證跳的時候仍然滿足當前位置的值 \(>A_y\) . 如果跳到的區間包含了 \(y\) ,那么就輸出 \(1\) ,否則不能確定,輸出 \(0\) .
\(A_x<A_y\) 的情況類似。
\(\Theta((n+q)\log n)\)
code見我的題解 solution-洛谷博客solution-cnblogs
提交答案題。
data1-2 是直接暴力\(\Theta(n \times 2^k )\) 其中 \(k\) 為條件跳轉操作的數目。
data3 是分塊暴力。
data4-6 都是直接DP.
data7-8 是分塊討論然后DP.
data9-10 和data7-8基本差不多,但是有一些不符合規律的點要特殊考慮。
首先如果不加入邊 \((x,y)\) 那么方案數為所有點入度的乘積。
我們要計算的是強制選取邊 \((x,y)\) 的情況下,能形成樹形圖的方案數
方案數為除去y的所有點入度乘積 - 形成環的方案數。
形成環的方案數可以在 DAG 上 DP 解決。
\(\Theta (n+m)\)
LOJ#6051. 「雅禮集訓 2017 Day11」PATH
注意:本題解數組下標從 \(1\) 開始
不難發現概率為可行方案數/總方案數。
總方案數顯然為 \(\large \frac {(\sum\limits_{i=1}^{n} a_i)!}{\prod\limits_{i=1}^{n} a_i!}\)
可行方案數如何計算?
考慮記 \(t_{i,j}\) 表示第 \(i\) 維 \(x_i\) 的值剛好加到 \(j\) 的時間。
不難發現只有 \(i \leq n\) 且 \(j \leq a_i\) 的時候, \(t_{i,j}\) 才有意義, 並且 \(t_{i,j} < t_{i,j+1}\)(如果存在) , \(t_{i,j} < t_{i+1,j}\)(如果存在)
那么這就是一個給定形狀的楊表計數問題。
楊表計數問題的答案為 \(\large \frac {(\sum\limits_{i=1}^{n} a_i)!}{ \sum\limits_{i\leq n,j \leq a_i} Cnt(i,j)}\) , 其中 \(Cnt(i,j)\) 為 \((i,j)\) 這個格子的鈎長+1.
記 \(b_x = \sum\limits_{i=1}^{x} [a_i \leq x]\) , 不難發現如果 \((i,j)\) 在楊表內部,其 \(Cnt(i,j) = (a_i - j) + (b_j - i) + 1\) ,否則 \((a_i - j) + (b_j - i) + 1\) 會小於 \(0\) .
那么直接把式子拆成 \((a_i - i) + (b_j - j) + 1\) 即可,可以直接 \(NTT\) 或者 \(FFT\) 解決,最后乘上 \(\prod\limits_{i=1}^{n} a_i!\) , 而 \((\sum\limits_{i=1}^{n} a_i)!\) 這個巨大的階乘在兩個方案數相除的時候已經被消掉了,不需要處理。
\(\Theta(N\log N)\) , 其中 \(N\) 為 \((n+\max\limits_{i=1}^{n} a_i)\)
代碼見 : my solution
LOJ#6102. 「2017 山東二輪集訓 Day1」第三題
記斐波那契數列的第 \(n\) 項為 \(F_n\) .
結論1 : \(\gcd(F_n,F_m) = F_{\gcd(n,m)}\)
這個應該是經典結論了。
大概就是,首先有 \(F_{n+m} = F_{n-1}F_{m} + F_{n}F_{m+1}\) 且 \(\gcd (F_n,F_{n-1}) = 1\)
那么不難發現 \(\gcd(F_{n+m},F_m) = \gcd(F_n,F_m)\) .
結論2 : \(\texttt{lcm}(S) = \prod\limits_{T ∈ S,T \neq ∅} \gcd(T) ^ {(-1)^{|T|+1}}\)
不難發現這個式子和對每個質因數進行 \(min-max\) 容斥等價,於是得證。
考慮計算出每個 \(F_{gcd(T)}\) 的次數,那么直接 Dirichlet 前綴和 一下即可。
因為最后需要快速冪,所以復雜度為 \(\Theta (n \log n)\) . 如果不想寫 Dirichlet 前綴和 , 也可以寫 \(\Theta(n \ln n)\) 的暴力,但還是跑的飛快?
代碼見 : my solution
LOJ#6059. 「2017 山東一輪集訓 Day1」Sum
考慮記 \(F_{n,m,r}\) 表示有多少個 \(n\) 位數 , 滿足各位數之和為 \(m\) ,且對 \(p\) 取模的結果為 \(r\) .
不難發現我們只需要支持 \(F_{n} -> F_{n+1}\) 和 \(F_{n} -> F_{2n}\) 就可以了。
\(F_{n} -> F_{n+1}\) 可以直接枚舉下一位數是什么,暴力轉移,單次復雜度 \(\Theta(10pm)\)
\(F_{n} -> F_{2n}\) 需要卷積,實現的時候注意不要用過多的 NTT , 3p 次就夠了 , 單次復雜度 \(\Theta(p^2m+pm\log m)\)
總復雜度 \(\Theta (pm(10+p+\log m)\log n)\)
代碼見 : my solution
LOJ#6068. 「2017 山東一輪集訓 Day4」棋盤
考慮把一段連續的空地縮起來,形成一些"行"和"列"。
考慮一個網絡流模型。
S -> 行,流量無限制,費用 \(f(flow) = \frac{flow (flow+1)}{2}\) , 列 -> T , 流量無限制,費用 \(f(flow) = \frac{flow (flow+1)}{2}\)
對於每個非障礙點,所在行 -> 列,流量為 1 ,費用為 0。
至於這個 \(f(flow) = \frac{flow (flow+1)}{2}\) , 我們把它拆成一堆流量為 1 , 費用分別為 0,1,2,3,4,...,5 的邊。
最后因為 S -> 行不會用超過這一"行"里的點數的流量,列 -> T 類似,所以我們只會連 \(\Theta (n^2)\) 條邊。
然后直接増廣即可,注意到詢問很多,要從小到大排序之后增加流量。
復雜度 \(O(EK(n^2,n^2))\) , 實測 ZKW 跑的很慢,因為詢問可以覆蓋滿 \(1\) \(\cdots\) \(n^2\),這時候顯然比 EK 慢。
代碼見 : my solution
LOJ#6062. 「2017 山東一輪集訓 Day2」Pair
對每個數 \(a_i\) 求出它能匹配的 \(b_j\) 的數目,記為 \(c_i\) 。
考慮 Hall 定理,對於 \(c_i\) 的一段長度為 \(m\) 的連續子段,記 \(s_i\) 為 \(\leq i\) 的 \(c_i\) 的數目,因為 Hall 定理所以有 \(s_i \leq i\) , 並且如果滿足 \(s_i \leq i\) 那么一定有完美匹配。
那么直接線段樹上維護 \(s_i - i\) 的 \(\min\) 即可。
\(\Theta (n\log m)\)
代碼見 : my solution
LOJ#6065. 「2017 山東一輪集訓 Day3」第一題
枚舉 \(\Theta(n)\) 種正方形的邊長 \(L\) , 不難發現在選的 \(6\) 條邊中只可能有 \(2\) 條 / \(3\) 條 邊的長度為 \(L\) .
有 \(2\) 條邊長為 \(L\) :
另外兩條邊分別由兩個比 \(L\) 小的數拼接而成。枚舉拼成 L 的方式 ( 即 \(L = x + y\) ,\((x \leq y)\) 的 \(x\) 和 \(y\) ) , 不難發現每種方式之間相互獨立,然后分別考慮一下只用這種方式 / 使用兩種不同方式 的方案數並求和即可。
有 \(3\) 條邊長為 \(L\) :
剩下的一條邊由三個加起來 \(=L\) 的數字拼接而成,不妨設 \(L = x + y + z(x\leq y\leq z)\) , 先 \(\Theta(n)\) 處理 \(x = y = z\) 或者 \(x = y < z\) 或者 \(x < y = z\) 的三種情況。
最后 \(x < y < z\) , 枚舉 z 之后變成查詢前 \(i\) 種數拼成 \(L-z\) 的方案數 , 這個可以離線下來做。
\(\Theta(n^2)\)
代碼見 : my solution
因為物品的價格不超過 \(300\) , 所以考慮每種體積的物品一起處理,然后按照對 % m 的余數分類並 DP.
不難發現由於 DP 轉移的權值滿足四邊形不等式,所以對於 % m 同余的 DP 狀態滿足決策單調性,因此直接分治解決即可。
\(\Theta (Cn\log n)\)
代碼見 : my solution
LOJ#6033. 「雅禮集訓 2017 Day2」棋盤游戲
把每個非 '#' 的格子當成點,共用邊的格子所代表的點之間連一條邊,不難發現這是個二分圖。
不難發現這個二分圖上的博弈,先手必勝當且僅當起始點一定會被包含在最大匹配中,否則后手只要一直走匹配邊就贏了。
那么我們判斷每個點是否可以成為這樣的起始點即可。
求最大匹配的部分可以使用匈牙利算法也可以直接網絡流,復雜度為 \(\Theta(n^2m^2)\) 或 \(\Theta((nm)^{1.5})\)
代碼見 : my solution