友情提醒:大部分題選自opentrains,之後有訓練須要的同窗慎重查看。算法
C
題意:給出一個長度爲 \(N(\leq 10^5)\) 的 \(DURL\) 操做序列。想一想一隻畫筆在無限大的平面上畫線,保證線能夠相交但不會重合,且最終構成一個迴路。問畫出的圖形最少須要用幾種顏色染色(使得邊相鄰的區域顏色不一樣)?
題解:數組
E
題意:有一個圓形披薩,圓心在 \((0,D)(D > 0)\) 。桌面是 \(x\) 軸上側。將披薩等分切成\(N\)塊(水平沿 \(x\) 軸正方向是第一刀)。如今要一塊一塊取小披薩。沒有被取過的披薩原本是粘成一個總體的。注意任意時刻,不能有一個總體的披薩掉下桌面(重心 \(\leq 0\))。問可行的取用排列有幾種。
題解:先用積分預處理出一段披薩是否能屹立在桌上。而後區間DP一下便可。函數
K
題意:在 \([10^6,10^6]\) 平面裏隨機撒 \(N(2 \leq N \leq 10^5)\) 個點。求最近點對的距離。
題解:利用隨機花式作。測試
A
題意:有 \(N (\leq 30)\) 個交易所和 \(M\) 個可行交易方案 \((x,y,p,q)\) ,表示交易所 \(x\) 裏每單位的錢能夠換成交易所 \(y\) 裏 \(p\)元前,且最多交易 \(q\) 次。\(|p|,q \leq 100\)。求最多能掙多少錢。
待補。優化
E
題意:用 \(N (\leq 500)\) 個邊長是 \(1 \times 1\)的正方形拼出一個規則幾何形狀。求拼成最小周長的形狀的方法有幾種。(擺放位置已經肯定,即四個角上輪換算不一樣方案)
題解:最終形狀確定是 \(a \times b\) 的長方形摳掉一些。枚舉每一組\((a,b)\)統計答案。
研究一下「摳」的規則。設 \(L_i,R_i\) 表示每行連續的正方形位置,顯然要保證 \(L_i\) 先遞減再遞增,\(R_i\) 先遞增後遞減,且 \(L_i\) 要取過 \(1\) ,\(R_i\)要取過 \(N\)。能夠直接根據這些規則從上到下進行DP。ui
G
題意:求 \(N (\leq 500)\) 個點的排列中,能被分解成三個遞增序列的排列有幾種。
題解:待補。spa
A
題意:給出由 \(N(\leq 10^5)\) 個單詞的字典和 $Q(\leq 10^5) $個詢問,每次給出兩個串 \(pre,suf\) ,問有多少個單詞以 \(pre\) 爲前綴,以 \(suf\) 爲後綴,且它們不重疊。字符串總長 \(\leq 5 \times 10^5\)
題解:這兩維的限制很難搞。由於一開始單詞的順序是無關的,咱們能夠先按字典序排序。這樣,前綴是固定值的單詞必然是連續的。咱們倒着創建trie,每次按\(suf\)走一走,即詢問:當前 \(trie\) 子樹下有多少個開頭知足在區間 \([L,R]\) 中的。
注意還有棘手的限制:不能重疊。即詢問串的長度必須 \(\geq |pre|+|suf|\) 。爲了破解這個限制,我就離線先按詢問的長度排序,動態往dfs序裏丟一個數,或者詢問一段區間裏裏另外一維權值在 \([L,R]\) 的數有多少個。這個是經典的2個log帶修改主席樹的作法。
其實只要容斥地減掉便可。不合法的必定是重疊的,咱們直接暴力枚舉重疊部分長度,用hash去全局判一判便可。3d
B
題意:一共有 \(5 \times 10^5\) 組數據。給出圓裏的兩個點 \(P\) 和 \(Q\) ,保證\(|OP|=|OQ|\)。在圓周上找一個 \(D\) ,使得 \(|DP|+|DQ|\) 最小。
題解:數據組數很大,三分須要一點黑科技。 三分時其實不必三等分點 。若是 \(m_1\) 和 \(m_2\) 每次都取在 \(mid=\frac{l+r}{2}\) 的附近,它的效率就會接近二分了。考慮到一些精度問題,建議與 \(mid\) 隔得稍微遠一點。
考慮解析解怎麼求,這裏須要圓的反演的知識。分別對 \(P\) 和 \(Q\) 作圓的反演點,類似比爲 \(|OP|:r\)。由於比例同樣,因此等價於求\(|DP'|+|DQ'|\)的最小值。若是 \(|P'Q'|\) 與圓有交,交點即是 \(D\) ;不然能夠假想一個以它們爲焦點的橢圓,咱們一點點放大這個橢圓,它第一次與圓的交點即爲所求,此時就在中垂線位置。指針
H
題意:給出 \(N(\leq 10^5)\) 個數的排列和 \(M(\leq 10^5)\) 個詢問。每次給出 \(L,R\) ,求\(\sum \limits_{i=L}^R \sum \limits_{j=i+1}^R \sum \limits_{k=j+1}^R [gcd(p_i,p_j)=p_k] \times p_k\)。
題解:離線,枚舉每個右端點,維護此時左端點的答案。由 \(p\) 是一個排列,每次加入 \(i\) 後,咱們能夠暴力枚舉 \(p_i | p_j (j<i)\)。
若是從右往左掃描,如今問題轉化成:把一個數加入集合;或者問集合裏與某個數互質的數有多少。這是個經典問題,只能暴力容斥。爲了減小常數,每次加入一個數的時候,只在它 \(mul \ne 0\) 的位置算貢獻。blog
C
題意:考慮這樣一個題:把 \(0\) 和 \(1\) 填入 \(N(\leq 60)\) 位的格子。還有 \(m(\leq 100)\) 個進制串,表示它們不能是某個合法方案的子串。問合法的方案總數 \(n\) 。如今給出這個 \(n(\leq 10^9)\) ,要求構造一種合法方案。
題解:待補。
F
題意:有 \(k(\leq 10000)\) 輪遊戲。每一輪會獨立地隨機一個 \(1\) ~ \(n(\leq 10000)\) 之間的數,能夠選擇取這個數或者 \(skip\) 。必須正好取 \(3\) 個數,問最優決策下,取的 \(3\) 個數是等差數列的機率。
題解:設 \(f_{i}\) 表示一共玩 \(i\) 輪成功的機率。轉移顯然爲:\(f_i=\frac{1}{n} \sum \limits_{j=1}^n \max(f_{i-1},g_{i-1,j})\)。其中 \(g_{i,j}\) 表示還剩下 \(i\) 輪,以前已經取了一個數字 \(j\) 的最優成功機率。而後 \(g_{i,j}=\frac{1}{n} \sum \limits_{k=1}^n \max(h_{i-1,k,g},g_{i-1,j})\) 。其中 \(h_{i,j,k}\) 表示剩下 \(i\) 輪,已經選出兩個 \(j\) 和 \(k\) 的成功機率。 \(h\) 已經能夠直接算了。且注意到,計算 \(g\) 枚舉的 \(k\) ,本質不一樣的只有 \(4\) 種(已經肯定了兩個數,符合要求的第三個數最多隻有 \(3\) 個),咱們能夠合併相同的狀況。最後複雜度 \(O(NK)\) ,滾一滾數組便可。
H
題意:給出一個 \(n \times m(n,m \leq 1000)\) 的01網格。每次能夠翻轉一行,一列,或者任意一條(反)對角線。求打印一種能翻轉成全1的方案。
題解:
C
題意:維護一個 \(N(\leq 10^5)\) 個數的可重集(數字 \(\leq 10^9\) )。有 \(Q(\leq 10^6)\) 種操做,分爲兩種:①問目前第 \(k\) 小的數;②將全部 \(> x\) 的數都減掉 \(x\)。
題解:要動態地求第 \(k\) 小,至關於要實時地維護出這個集合。爲了用上一些均攤的特性,咱們把②操做要維護的數分類。
對於 \(y \in [x+1,2x]\) 的這些數,其實咱們是能夠暴力找出來刪掉它們,再暴力插回平衡樹的。由於每操做一次,值必然小於原來的一半。
對於 \(y > 2x\) 的這些數就不能暴力了。但注意到,它們減去了 \(x\) 後依然大於 \(x\) ,與以前全部數的相對大小保持不變!這樣咱們只需在這一段裏打一個區間減標記便可。
I
題意:給出一個凸包 \(N(\leq 10^5)\) 。問凸包上有多少個點對,知足以它們爲直徑畫圓,該圓能夠蓋住凸包上的全部點。
題解:由於直徑是圓裏最大的弦,因此符合要求的圓的直徑必然是凸包的最遠點對的距離。
首先介紹一個經典算法:求每個點的最遠點。
顯然一側繞着凸包走,另外一側是單調的。但注意這不是徹底決策單調性,即最優勢周圍是不具有單調性的。
最簡單的作法就是分治。具體地,將凸包倍長,定義
\[\begin{equation} cost_{i,j}=\left\{ \begin{aligned} dist(i,j) & i \leq j < i+n\\ -dist(i,j) & j < i , j \geq i+n\\ \end{aligned} \right. \end{equation}\]
直接對其作要求的點爲 \([1,n]\) ,分治決策點爲 \([1,2n]\) 的DP便可。(注意不合法那一段必定要取負,以保持分治的單調性)
這題咱們會發現,若是一組點對合法,那麼全部距離爲直徑的對踵點都合法。因此只需暴力check一組便可。
B
題意:有一個 \(N \times N(N \leq 1000)\) 個格子,每個格子均勻隨機一種 \([1,k](1 \leq k \leq N^2)\) 的顏色。一個矩陣的價值是裏面不一樣顏色的數量。求全部子矩陣的價值之和。
題解:待補。
C
題意:一個數列前 \(5\) 項是 \(\{1,2,4,6,3\}\) ,以後每一 個\(a_i\) 知足:它是與 \(a_{i-1}\) 不互質、且以前沒出現過的最小的正整數。求它第 \(N(\leq 3 \times 10^6)\) 項的值。
題解:直接對於每個質數,維護 \(f_i\) 表示含該質數的最小沒出現過的數是多少。全局維護一個是否出現過的flag數組,每次枚舉 \(a_{i-1}\) 的質數,用 \(f_i\) 更新,維護 \(f\) 時暴力往上走便可。複雜度爲 \(O(N \log N)\)。
D
題意:平面裏有 \(N(\leq 1000)\) 個點。問有多少條長度爲 \(6\) 的鏈,知足這 \(6\) 個點互不相同,線段方向交替(第一條線段是向左轉,第二條向右轉……),且每次轉向角都是鈍角。
題解:待補。
L
題意:有 \(k(\leq 10)\) 個寄存器,初始時 \(0\) 號點裏的值是 \(x\) ,別的點都是\(0\)。給出\(m(\leq 15)\)操做,分爲兩種:①將一個寄存器的值加到另外一個上。②某個寄存器裏的值加一。全部操做都是在模域 \(P\) 下進行的。再讀入一個 \(K\) 位的字符串表示 對\(P\) 的限制:每一位是 \(0\)~\(9\) 中的一個數或者 \(?\) (能夠填任意數字);第一位必然是肯定的數字。
設全部操做作完後 \(0\)號點獲得的值是 \(y\) 。如今只給出 \(y\) ,對於全部合法的pair \((x,P)\) ,求 \(x\) 的和。注意要保證 \(0 \leq x,y<P\),且一個 \(x\) 若是有多個 \(P\) 符合,答案算屢次。
題解:這題特別複雜。首先前面的寄存器沒啥卵用。題目轉化成,\(Ax+B=y(\mod P)\),給出 \(P\) 的數碼限制和 \(y\) ,求全部合法解的 \(x\) 之和。
\(P\) 有數碼限制,應該要數位DP;但有取模運算在彷佛很差搞。由於寄存器操做 \(m \leq 15\), \(A\) 和 \(B\) 不會很大(幾千)。咱們能夠枚舉這個等式的商 \(k\) ,將其改寫成 \(Ax+B=y+kP\) 。若是 \(B<P\) (爲了知足這個條件,\(P\) 限制位數小的時候咱們能夠暴力枚舉 \(P\) 驗證),又由於 \(x < P\),因此 \(k\) 的枚舉範圍爲\([0,A]\)。
再把式子寫成 \(\frac{Ax+B'}{k}=P\)。這個式子必需要整除,設最小合法解爲 \(x0\) (對應的 $P $稱爲 \(p0\) )。 \(x\) 每加一,分子增長 \(A\) ,那麼咱們能夠求一個\(dx = \frac{k}{gcd(A,k)}\),表示 \(x\) 至少增長這麼多才能又一次整除;對應的 \(dp = \frac{A}{gcd(A,k)}\)。注意還要知足 \(x < P\) ,因此第 \(i\) 組解若是成立,要知足 \(x0 + dx \times i < p0 + dy \times i\),由 \(k \leq A\) ,合法的 \(i\) 是一個後綴(要大於等於某個值)。
求 \(\sum x\) 比較麻煩,考慮先求出 \(\sum P\) ,最後式子轉化一下便可。
問題變成了一個有下界要求的數位DP。由於合法的 \(P\) 是一組等差數列,DP的時候咱們還要再記一維 \(mod\) 表示目前填的 \(P\) 的前綴對 \(dp\) 的模數(最後被統計進答案的 \(P\) 需知足 $P \mod dp = p0 \mod dp $ )。注意不光要記錄目前以前填好的前綴全部合法 \(P\) 的和,還要記合法 \(P\) 的個數(這樣才能幫助轉移前者)。常數略大,須要卡常。
L
題意:給出一個 \(N(\leq 2 \times 10^5)\) 個點和 \(M(\leq 5 \times 10^5)\) 條邊的有向圖。對於每個都詢問:若是刪了這個點,這張圖的強連通份量個數是否會增長。
題解:每個SCC單獨作。考慮固定一個點 \(O\) 。若是點 \(X(X \ne O)\) 是合法點,那麼至少存在一個子SCC集 \(B\) ,知足它和 \(O\) 所在的子SCC集 \(A\) 不能互相到達。先從 \(O\) 點開始跑一個支配樹。假設只存在 \(B\)->\(A\) 的邊,咱們會發現, \(X\) 是 \(B\) 集合的全部點的支配點;反之 \(A\) -> \(B\) 有邊,只需將全部邊都反向,那麼 \(X\) 依然是它們的支配點。因此,咱們跑正反各一次支配樹,若是一個點至少一次成爲某個點的祖先,就是合法點。最後還要特判 \(O\) 點,直接刪除它跑一遍tarjan便可。
題意:有 \(N(\leq 3000)\) 個院子排成一排,相鄰兩個院子有一個柵欄。每一個柵欄的高度是 \((L_i,R_i)(R_i \leq 10^6)\) 裏的一個隨機整數。
還有 \(M(\leq 3000)\) 個殭屍,給出它們初始所在的院子和最多能跳的高度。對於全部柵欄的可能局面,問「至少存在一個院子不可能被任何殭屍走到」的機率。答案對大質數取模。
題解:有點意識流的DP。設 \(f_{i,j}\) 爲前 \(i\) 個院子都能被殭屍到過,且能走到院子 \(i\) 的最強的殭屍是 \(j\) 的機率;再設\(g_{i,j}\)爲前\(i\)個柵欄不能全被殭屍到過,且必須有一個能力至少爲 \(j\) 的殭屍從右側跳到第 \(i\) 個院子來,能使前 \(i\) 個院子都被到過。對於一個 \(i\) , \(f\) 和 \(g\) 顯然是不交的,並且它們的機率和是 \(1\) 。每次轉移的時候,分狀況討論便可。轉移 \(g\) 的時候複雜度是 \(O(N)\) 的,還須要一個前綴和優化。總複雜度 \(O(N^2)\)。
B
題意:有一個 \(6 \times 6\) 的棋盤。如今打亂棋盤上棋子。每次能夠對一行或者一列循環移動1格。構造一種能恢復成原來狀態的操做序列。
題解:若是咱們能作到交換兩個格子,這題也就結束了。惋惜我並無搞出來。
對於一個點 \((x,y)\) ,若是對其執行了 \(DRUL\) 的操做,別的數沒有發生變化,而\((x,y),(x,y+1),(x-1,y)\)這三個字符發生了循環位移。同理,咱們也能發現 \((x,y),(x,y-1),(x-1,y)\) 的循環位移的方法。前 \(4\) 行每次用三角置換把數字移動到目標位置。最後兩行是一列一列填好的,最後還會剩下兩個字符(即便是反的也沒救了)。到這裏也能說明,能互相到達的狀態的等價類最多爲 \(2\) 。實測發現等價類爲1,因此每次對於一個初始態,咱們能夠先隨機shift一下,再按這個操做拼。每次正確率的指望是 \(\frac{1}{2}\)。
C
題意:給出 \(b(\leq 5 \times 10^4)\) 進制下,數碼 \(1\)~\(b-1\) 分別對應的字符串(總長\(\leq 5 \times 10^5\))。再給出一個很長的字符串 \(S(|S| \leq 3 \times 10^5)\),找到它的一個子序列 \(S'\),使得$ S'$ 能能不重不漏地分解成一些數碼對應的字符串,且數碼構成的數字最大。要求輸出方案。
題解:求最長的數字長度仍是比較好作的。設 \(f_i\) 表示後綴 \(i\)~\(n\) 中能拼成的最長長度,每次枚舉從 \(i\) 開始最小的能覆蓋的子串 \([i,j]\),\(f_i=\max(f_{j+1}+1, f_{i+1})\)。還要求具體方案的話,由於數字必定是首位越大越優,增設 \(g_i\) 表示在知足長度爲 \(f_i\) 的狀況下,當前第一位最大是多少。轉移時,找合法覆蓋串 \([i,j]\) 的最大可能數碼。注意 \(j\) 還要知足,\(f_{j+1}=f_i-1\)。
以上是暴力轉移的作法。在比賽時,想到了一個\(naive\)的分塊作法。設一個閾值 \(last(=100)\) 。把數字對應的串按長度排序,稱後 \(last\) 個爲大串,剩下的爲小串。dp轉移的時候,分別考慮這兩類串的貢獻。對於小串,長度都是比較小的,咱們直接暴力枚舉 \(j\) ,而後看一下給定子串是否存在一個對應數碼(因此咱們還能將小串的長度去重來枚舉,減小常數);對於大串,每次dp第 \(i\) 位時直接掃描全集,hash值比對一下便可。複雜度是 \(O(N(K+last))\) 的,其中 \(K=min(\sqrt{5 \times 10^5 - l \times last},l)\), \(l\) 是一個任意值(表示後 \(last\) 個串的長度)。手寫hash+64位天然溢出能夠卡過。
事實上有很簡單的作法。將全部數碼串反向建 \(trie\) 圖。倒着枚舉 \(i\) 的時候,直接走 \(S_i\) 這條邊。這樣當前節點 \(p\) 的 \(fail\) 樹上的祖先都是能匹配的串。預處理一個點到根路徑上最短匹配串,就能夠支持對 \(f\) 數組的轉移了。 \(g\) 數組的話,由於有一個長度限制,若是同時維護的話,須要在 \(fail\) 樹上詢問某一段祖先的最大值。但其實,咱們能夠等 \(f\) 數組作完後,從前日後逐位肯定去肯定具體方案。每次找到以後 \(f\) 連續的那一段,從結尾出開始走 \(trie\) 圖,這樣咱們只會詢問到根路徑上最大匹配串的數碼。
D
題意:多組數據。每次給出一個 \(N(\leq 2000)\) 個整數的集合,數字範圍爲 \([0,10^9]\)。找出一個長度最長的等差數列。
題解:開始想到的作法是:枚舉任意兩個數 \(a_i,a_j\) ,將這個pair插入 \(a_j-a_i\) 這個集合裏。最後依次掃描每個集合,每次貪心地跑一遍便可。可是如何劃分這些集合呢?直接排序也是會TLE的,首先hash可能也會卡常。
事實上,排完序後,直接設 \(f_{i,j}\) 表示結尾兩個數是 \(a_i,a_j\) 時的最長長度。而後找到一個 \(k\) ,使得 \(a_j-a_i=a_k-a_j\) ,轉移到 \(f_{j,k}\) 。注意到,枚舉 \(j\) 的時候,對應的 \(k\) 是單調的,指針掃一掃便可。
D
題意:給出一個二進制數 \(R\),它是由01串 \(S(|S| \leq 50)\) 重複 \(K(\leq 10^5)\) 次獲得的。要在 \([0,R)\) 裏選擇 \(N\) 個互不相同的數,使得它們的xor值是0。求方案數模 \(10^9+7\)。
題解:還不會帥氣的作法。
先寫一個我搞出來的求容許相同的數的答案。考慮直接數位DP,對每個數都開一個0/1表示是否已經嚴格小於 \(R\) ,轉移時枚舉每一個數這一位填0/1(均可以用一個二進制狀態 \(U\) 來描述)。這樣複雜度是 \(O(|S| \times K \times 2^N)\) 的。 \(K\) 很大,考慮倍增 \(K\) 。關於合併的話,我並不會特別優美的作法。只會設 \(f_{S,T}\) 表示通過一段 $R \(以後,原dp數組的狀態\)S$對新dp數組的狀態 \(T\) 的貢獻的係數。預處理走一段的複雜度上界是 \((4^N \times |S|)\) (枚舉子集的子集)。不停地把f合併來倍增。每次合併複雜度也是 \(O(4^N)\)。
G
題意:初始有一個字符串 \(p\) 和空串 \(S\) 。重複若干次操做,每次往 \(S\) 裏的隨機一個位置插入一個 \(p\) 。給出最終狀態的 \(S(|S| \leq 200)\),求長度最短(若是同樣,字典序最小)的合法的 \(p\)。
題解:要長度和字典序最小,應該是枚舉+check的套路。先枚舉一個 \(|S|\) 的約數 \(len\) 。 \(p\) 必然是 \(S\) 的一個子串,咱們再花 \(O(N)\) 的時間,能夠找到全部可能的 \(p\) ,最後驗證一下便可。
驗證時,每次找到最靠前的 \(p\) 並刪掉是錯的。好比\(S=ababaa,p=aba\)也是合法的。
注意到,雖然一塊p可能被斷成若干截,但夾在其中的每一段,必然是能獨立消光的。咱們能夠 \(f_{i,j}\) 表示區間 \([i,j]\) 是否能合法。注意 \(j-i+1\) 不要求是 \(len\) 的倍數。若是有餘數,咱們要求多餘的部分正好是 \(p\) 的前綴。轉移時考慮第 \(j\) 個字符。
一種狀況是,它和以後的零碎字符會拼成一段,即 \(f_{i,j}|=f_{i,j-1} and a_j = prefix_{(j-i) \mod len+1}\);
或者說,對於以後的零碎部分而言, \(j\) 是屬於夾在它之間的整塊,那麼 \(f_{i,j}|=f_{i,j-k \times len} and f_{j-k \times len+1,j}\)。
最終複雜度爲 \(\sum \limits_{k|N} (N-k+1) \times N^2 \times \frac{N}{k}=O(N^4)\)
H
題意:一個壞的售貨機有 \(N(\leq 10^5)\)個物品,每一個物品有 \(a_i(\geq 1)\) 個。還有 \(N\) 個按鈕,第\(i\)個按鈕指向物品 \(f_i\) 。每指定一次 \(i\) 後,若是物品 \(i\) 和物品 \(f_i\) 都有貨,要支付 \(C_i\) 的代價,但會跳出物品 \(f_i\) 。再給出每一個物品賣掉的價格 \(D_i\) ,問操做一通最多能賺多少錢。
題解:挺有趣才摘錄的,不難。經典模型,構出來的必定是一棵基環內向樹。若是隻是樹,從根開始直接向外貪心便可。
考慮環的話,環上指向一個點 \(X\) 的邊必需要大於 \(X\) 子樹朝它的邊(不然刪掉它便可作一遍樹便可)。先所有取到 \(1\) ,最後必須損失一個點,找一個最小的便可。
A
題意:給出 \(N(\leq 15)\) 個整數區間。在每一個區間裏等機率隨機一個實數,求總和的絕對值的指望。模大質數。
題解:待填坑。
C
題意:給出一張 \(N(\leq 10^5)\) 個點, \(M(\leq 10^5)\) 條邊的無向圖。問最少幾條 \(path\) 能夠覆蓋每條邊正好一次。要輸出方案。
題解:度數爲奇數的點必然只有偶數個。將它們隨意鏈接,就能獲得一張歐拉圖。跑一個歐拉路徑,再把鏈接處斷開便可。
F
題意:給出一個 \(N \times M (N,M \leq 3000)\) 的棋盤。給每個格子染黑色或白色的一種,問至少有 \(A\) 行全黑,\(B\) 列全黑的方案數。
題解:在一維狀況下,算正好是 \(x\) 個符合要求的答案,咱們能夠倒着來\(DP\)。即 \(g_x=f_x-\sum \limits_{i=x+1}^n g_i \times C_i^x\) 。可是二維下,這個是\(O(N^4)\)的。
反思一下,一維的時候,其實咱們還能夠直接容斥算 \(x\) 處的答案。 \(g_x=\sum \limits_{i=x}^n f_i \times C_i^x \times (-1)^{i-x}\)。
並且這個也是能夠無傷拓展到二維的。因此如今咱們會 \(O(NM)\) 的複雜度算 正好有 \(A\) 行 \(B\) 列的方案數 了。
假想咱們枚舉全部\((A',B')(A' \geq A),B' \geq B)\)分別作一遍容斥,這樣依然是 \(O(N^4)\) 的。
但咱們能夠反過來考慮,對於一組 \((x,y) (x \geq A,y \geq B)\),計算它對全部 \((A',B')\) 的貢獻。係數是對一個組合數的式子求和,拆一拆能夠用前綴和優化。最終效率是 \(O(NM)\) 的。
A
題意:要選出六邊形網格(見下圖)裏的 \(N(\leq 10^9)\) 個點,而後用連續圍牆把它們圍住。圍牆也佔據格子,且不能和選出的點重合。能夠多圍一些空的格子。問圍牆通過的最少的格子數。
題解:若 \(N\) 正好等於一個正六邊形內部的點數,那麼外面圍一圈必然是最優的。以後每增長1的圍牆,能夠「拓寬」一條邊界。假設六邊形邊長是 \(e\),向外拓展六次後,能多圍的點數分別爲 \(e-1,e,e+1,e,e,e\)。因此一點一點模擬拓寬過程便可找到最優解。複雜度\(O(\sqrt N)\)。
B
題意:在 \(N \times M(N \leq 6,M \leq 300)\)的網格里放骨牌。每個骨牌都是 \(1 \times 2\) 的,且正好一端黑一端白。特別的,對於兩種骨牌放置方案,若是其帶來的染色結果相同,咱們認爲是同一種方案。求放滿骨牌的方案數模一個大質數。
題解:很難直接統計骨牌放置的方案,由於處理不了等價的狀況。
先考慮,若是給出一種染色結果,是否存在一種骨牌放置方案?能夠一列一列狀壓DP過去判斷。這樣就不用考慮相同的骨牌放置方案了。那麼咱們能夠在以前的DP中,額外開兩維 \((i,j)\),表示目前顏色塗到 \((i,j)\),且目前的骨牌能放置的結構爲 \(S\)的方案數。每次枚舉這一格顏色是 \(0\) 仍是 \(1\)。最後把最終態裏合法的顏色的方案數加起來便可。狀態數不滿 \(2000\)。
G
題意:在 \(N \times N(4 \leq N \leq 100)\) 的國際象棋棋盤上有兩顆子。選手操縱後,\(judge\)程序操縱馬。要求在 \(K (K \times N \leq 10000)\) 步以內把馬吃掉。
題解:大概會了。待補。
H
題意:設 \(f(x)=\prod \limits_{i=1}^n (1+a_i x)\),\(g(x)=\prod \limits_{j=1}^m (1+b_j x)\)。(直接給出 \(f\) 和 \(g\) 的係數)。
求 \(h(x)=\prod \limits_{i=1}^n \prod \limits_{j=1}^m (1+a_i b_j x)\) 的前 \(k\) 項係數,模NTT質數。\(n,m,k \leq 10^5\)
題解:用到一步精妙的泰勒展開(或許是多項式基本操做?)
\(f(x)=exp(\sum \limits_{i=1}^n ln(1+a_i x))=exp(\sum \limits_{i=1}^n \sum \limits_{k=1}^{\infty} \frac{(-1)^{k+1}}{k} \times {a_i}^kx^k)=exp(\sum \limits_{k=1}^{\infty} \frac{(-1)^{k+1}}{k} (\sum \limits_{i=1}^n {a_i}^k) x^k)\)
\(g(x)\)同理。
\(h(x)=exp(\sum \limits_{i=1}^n \sum \limits_{j=1}^m ln(1+a_i b_j x))=exp(\sum \limits_{k=1}^{\infty} \frac{(-1)^{k+1}}{k} \times (\sum \limits_{i=1}^n a_i)(\sum \limits_{j=1}^m {b_j}^k) x^k )\)
因此 \(ln(h(x))\)能夠由這兩個函數取對數後點乘起來再調一下係數獲得。最後再 \(exp\) 回去便可。
J
題意:給出一個\(n(\leq 10^6)\)位的高精度數。判斷它是不是徹底平方數。
題解:NOIP模域作法再現江湖!咱們能夠指定一些質數 \(P\)。若是 \(n\) 是徹底平方數,顯然 \(n\) 在模域 \(P\) 下存在二次剩餘,即\(n^{\frac{P-1}{2}}=1\)。多測試幾回便可。
C
題意:經典題。給出一棵 \(N\) 個點的樹。設一條路徑的權值是它上面的顏色數。求全部路徑的權值之和。
題解:顯然對於每一種顏色分開考慮。這就變成了一個虛樹上DP的模型。
虛樹上不是全部點都是關鍵點。直接算包含關鍵點的路徑會比較困難。能夠容斥一下,算不包含的數量。
虛樹上也要額外統計原樹裏(且不在虛樹上)的點。能夠分類爲「虛樹上一條邊裏的點」和「虛樹上的點的其它子樹裏的點」。
I
題意:給出一棵 \(N(\leq 1000)\) 個點的仙人掌。求它前 \(K(\leq 10^5)\) 小生成樹的代價和。
題解:顯然每個環裏必須刪掉一條邊。
問題轉化成:給出\(N\)個集合,每一個集合裏有若干個數(數量總和 \(\leq N\))。如今要在每一個集合裏各刪一個數,求剩下數的和的前 \(K\) 小解。
有一個經典的二分作法。二分答案,暴力去DFS構造。一旦超過 \(K\) 可當即中止,複雜度上界 \(O(NK \log V)\)。
題解分析了一通,其實也能夠暴力。考慮一個一個去合併這些集合。
一種顯然的作法是,以前已經維護好了\(K\)個值。到目前這個集合 \(S\) 時,往堆里加 \(|S|\) 個元素,每一個元素開個指針一步一步從 \(1\) 推到 \(M\)。這樣每一輪複雜度是 \(O(K \log |S|)\),總複雜度是\(O(K \log \prod_{S_i})=O(KN)\)
J
題意:有 \(N(\leq 5 \times 10^4)\) 個物品,大小爲 \(i\) 的物品有 \(a_i\) 個(\(a_i < a_{i+1}\))。求拼出體積爲 \(1\)~\(2N\) 的方案數。
題解:經典的分段揹包。對於大小小於 \(\sqrt N\)的物品,直接應用隊列優化的多重揹包便可;對於更大的物品,能夠視爲無限揹包,且最多隻會放\(\sqrt N\)個,直接應用旋轉體積揹包便可(每次總體 \(+1\) 或者加入新的一個點)。
注意這裏體積要算到 \(2N\)。能夠先將物品視爲 \(2N\) 個,作一遍旋轉體積揹包。而後再考慮減掉 「用到體積大於\(N\)的物品」 的方案數。直接枚舉超過的物品體積(\(N+1\)~\(2N\)),剩下的調用直接的DP值便可。
H
題意:字符集爲前 \(k(\leq 26)\) 個小寫字母,填 \(N(\leq 500)\) 個格子。還有一個額外限制 \(S(|S| \leq 60)\) 。\(S=s1>t1|s2>t2|s2>t3 \dots\)。其中 \(s1,t1,s2 \dots\)是字符串,且保證對於一組 \((s,t)\),不可能存在一個字母同時屬於\(s\)和\(t\)。限制的含義是,若你填的方案裏出現過 \(s_i\) ,則最後一個 \(s_i\) ,必須早於最後一個 \(t_i\) 。求合法方案數。
題解:看上去很經典?是的。
注意到 \(|S| \leq 60\),因此最多隻有 \(15\) 個限制。設直接對全部限制一塊兒創建一個AC自動機。設 $f_{len,p,S} $ 表示填到第 \(len\) 位,走到了自動機的第 \(p\) 位,且目前對於限制的知足狀況是 \(S\) (\(S\) 是一個二進制狀態)的方案數。惋惜的是,這樣會TLE的。
主要仍是 \(S\) 太大了。考慮創建一種嶄新的自動機,能徹底刻畫出知足的某些限制,而不用 \(S\) 來描述。
因爲不知道如何形式化地創建自動機,咱們能夠暴力建。具體地,一個自動機上的點是一個狀態集合\(S\),表示目前對於第\(i\)個限制它匹配到了哪裏。(好比,若是還沒匹配完 \(s_i\) 就失配了,那從 \(s_i\) 頭開始匹配;超過 \(s_i\) 但沒匹配完 \(t_i\),則從 \(t_i\)開頭匹配;匹配完了 \(t_i\),又能夠從頭開始搞。注意,因爲 \(s\) 和 \(t\) 出現的字母都不同,因此不用考慮\(kmp\))。
能夠證實,建出的自動機大小不超過 \(10^6\),這樣只須要兩維DP了。
F
題意:給出 \(m(\leq 20)\) 個層層嵌套的循環語句。設循環變量分別爲 \(i_1,\dots,i_m\)。保證\(i_p\)的循環下界是\(1\)或\(i_q(q<p)\),循環上界是\(N\)或\(i_q(q<p)\)。求\(N \rightarrow +\infty\)時,該循環複雜度的最高項的係數。結果用最簡分數表示。
題解:首先,要產生複雜度,每個循環的下界都要小於等於上界。若是某一層循環 \(i_p\) 是從 \(i_u\) 循環到 \(i_v\) 的,那麼 \(i_u \leq i_p \leq i_v\)。對於每個 \(A \leq B\) 的關係,咱們從 \(A\) 到 \(B\) 連一條有向邊。這樣\(m\)個循環變量構成了一張圖。
首先求出這張圖的全部強連通份量。根據連邊的意義,每一個SCC裏的循環變量的取值必須徹底同樣。
那麼能夠等價地把每一個SCC縮成一個點,結果不變。如今得到了一張 \(m'\) 個點的拓撲圖。
由於循環的下界只能是\(1\),上界只能是\(N\),若是不考慮循環變量之間的大小限制,總遍歷次數是 \(N^{m'}\)。如今,咱們要額外考慮循環變量之間的限制,若是算出對應的實際遍歷次數 \(cnt\),那麼答案就是 \(\frac{cnt}{N^{m'}}\)
一個顯然可是重要的轉化:在 \(N \rightarrow +\infty\) 下,咱們能夠忽略新圖中存在兩個點取值相同的狀況。即你能夠認爲,全部點的取值兩兩不一樣。
考慮給這 \(m'\)個點任意兩個 \(rk\) 的合法排列 \(p_1,p_2\)(合法的意思是,知足拓撲圖的大小限制)。你會發現,\(p_1\) 和 \(p_2\) 遍歷到的次數(對應的取值方案數)是徹底同樣的。而後你進一步會法案,一個合法排列 \(p\) 與一個不合法排列 \(p'\) 遍歷到的次數也是徹底同樣的。
因此能夠轉化爲這樣一個問題:給出一張最多 \(20\) 個點的拓撲圖,問有多少種 \(rk\) 分配的排列,使得知足拓撲圖限制。合法分配數除以排列總數便是咱們要求的答案。這個直接 \(O(2^{m'} \times m')\) 的狀壓DP便可。
J
題意:給出 \(N(\leq 50000)\) 個數 \(a_i(a_i \ne 0)\)。設 \(A=\sum \limits_{a_i>0} a_i,B=-\sum \limits_{a_i<0} a_i\)。
再設
\(\begin{equation} w_i=\left\{ \begin{array}{rcl} \frac{a_i}{A} & & {a_i>0}\\ \frac{a_i}{B} & & {a_i<0}\\ \end{array} \right. \end{equation}\)
再設 \(sum_i\) 是 \(w_i\) 的前綴和。求 \(sum_i\)最大的位置 \(i\)。有 \(Q(\leq 50000)\) 次操做,每次修改一個數,而後回答一下。
題解:在一次單調修改後,後綴 \(sum_x\)都會變更,不利於維護。很容易想到分塊的操做。
\(sum_i\) 割裂成 「大於\(0\)」和「小於\(0\)」 兩維(如下簡稱 \(x\) 和 \(y\) )的前綴和,就能夠看作一個點了。由於 \(A\) 和 \(B\) 變更也很頻繁,沒有規律,咱們能夠把 \(A\) 和 \(B\) 當作變量去查詢。
具體地,對數列分 \(\sqrt N\) 塊。每塊無視以前的前綴和,從頭算出 \(sum_x\) 和 \(sum_y\)。對於詢問,本質是求 \((B,A)\) 和 \((sum_x,sum_y)\) 的最大點積值(其中前者在第一象限,後者在第四象限)。考慮點積的幾何意義,咱們只需對點集\(sum\),在第四象限維護出一個凸殼便可。詢問時,作一個垂直於 \((B,A)\) 的直線,從無窮遠處移動過來,碰到的第一個點即爲答案點。
上述要維護的東西能夠用二分+點積作到。
每次回答時,枚舉每個塊分別問一下。以前塊對後面塊的影響,至關於把凸殼平移了一段距離。其實最優勢依然不變。
每次修改時,暴力重建對應塊的凸殼便可。複雜度爲 \(O(Q \sqrt N \log N)\)。