退役前的做題記錄 Ⅰ
寫一下卡特蘭數加強數字敏感度:1 2 5 14 42
持續更新到退役(大概
Update: 把日記都刪了
P6689 序列
第一步發現對於左括號個數相等的結果序列,它們的出現概率也相等,這個是可以輕松 \(n^2\) Dp 出來的。
第二步我們需要求一個左括號個數確定的隨機序列的最長合法括號子序列期望長度。
掏出我們的重要結論:左括號為 1,右括號為 -1,設前綴最小值是 \(Smin\),答案就是 \(n-S_n+2\times Smin\)。
考慮將相鄰的左右括號匹配后消掉會形成這樣的:\())))((\),前綴最小值的絕對值就是這樣右括號的個數,玩一下發現是對的。
觀察發現 \(n-S_n\) 是固定的,我們枚舉 \(Smin\) 就可以得到答案了,那么用 \(Smin\le k\) 減去 \(Smin <k\) 的方案數就可以得到恰好的方案了,算小於的方案就相當於算不得碰到某條直線的方案數,應用折線法即可。
P4769 [NOI2018] 冒泡排序
做到上面那題想到這題了。
首先題意可以轉化為計數可以分成兩個上升序列的排列個數。
這個東西又可以轉化為經典的格子走路問題,我們貪心的這樣轉化:維護兩個上升的序列,選出排列的第一個數開頭當第一個序列,另一個序列當成開頭為 0,每掃到一個數能放第一個序列就放第一個序列,否則放第二個,不能放就說明不合法。
發現這樣一件事:第一個序列相鄰兩個數 \(x,y\),那么 \((x,y)\) 之間的數在第二個序列是連續且上升的,然后就可以看成格子走路了,從 (0, 0) 開始走路,走到 (n, n),只能向上向右走,每個向右拐點代表着第一個序列填了一個 y 坐標的數,向右平走表示在第二個序列里填了下一個該填的數(這個數是當前最小的未出現過的正整數),一個限制是我們不可以越過 y = x 這條線。
所以這題也不難了,要求字典序要大於 q,我們就枚舉一個前綴和 q 相等的部位,強制下一位大於 q 即可。
P6827 「EZEC-4」括號
這題 160 多個 A 的,出題組 A 了 150 多發真是喪心病狂。
暴力 dp 應該都會,以為有什么高妙的少一維狀態,沒想到是每次多跳一些。
狀壓預處理,暴力匹配每次跳一步,預處理以后我們可以一次跳多步,就這樣卡過去的???
CF755G PolandBall and Many Other Balls
設 \(F_n=\sum_{}f(n, k)x^k\) 其中 \(f(n,k)\) 表示 n 個球,k 次操作的答案。
我們有簡單的 dp。
\(f(n,k)=f(n-1,k)+f(n-1,k-1)+f(n-2,k-1)\)
用生成函數表示就是 \(F_n=(1+x)F_{n-1}+xF_{n-2}\)
這個東西可以矩乘優化,時間復雜度 \(\Theta(k \log k \log n)\)
組合數的辦法看起來非常簡便,事實上會當 \(n \ge 998244353\) 會因為分母為 0 而出鍋。
CF1054H Epic Convolution
\(1 \le n,m \le 10^5,a_i,b_i \le 1000,c < 490019\)
我們發現 \(P\) 是比較小的數。
設 \(A_k=\sum [i ^2\equiv k \bmod P-1]a_i,B_k = \sum[j^3 \equiv k \bmod P-1]b_j\)
有 \(Ans = \sum_{i=0}^{P-2}\sum_{i=0}^{P-2}A_iB_jc^{ij}\)
這個東西直接 CTZ 做即可。
[清華集訓2016] 你的生命已如風中殘燭
這題也超牛逼的!如果會了 Raney 引理那么這道題將秒切。
用卡特蘭數來引入一下吧。
相當於一個由 n 個 1 和 n 個 -1 構成的序列,要求前綴和都大於等於 0 的方案數。
Raney 引理其實使用條件限制並不少,這樣不平凡的構造也顯得非常巧妙。
Raney 是這樣一個事實:如果序列的 最大值 為 1,並且序列的和為 1,那么有且僅有一個位置 k 使得 \(s_k\cdots s_ns_1\cdots s_{k-1}\) 的前綴和都大於 0。
這個具體數學講的非常好就不再贅述。
我們給序列里的所有數字標上號,最后在除去,那么序列里有 n 個 1,我們在插入一個標號為 2n + 1 的 1 轉化為 Raney 引理的形式。
一共有 \((2n)!\) 個 ⚪ 排列,注意到所有的 1 都是等價的,誰他娘的生下來就有兩個腦袋,所以我們刪去最后一個 1 的概率就是 \(\frac {1}{n+1}\),那么卡特蘭數就是 \(\frac{{2n \choose n}}{n + 1}\) 了。
回到這題,我們發現最大值沒有限制,但最小值有,題目要求前綴和都 \(\ge 0\),我們取反,那么就是前綴和都小於等於 0,但是最大值限制為 1,題目里又保證了和為 0,那么就是所有的后綴和都大於等於 0,所以和上面一樣做就行了。
「PA 2019」Podatki drogowe
注意到永遠進不了位的,我們可以方便的使用線段樹維護 hash 值來比較兩個串的大小。
給定一個 k 並不好直接求對應的串,但給定一個串我們可以求出對應的 k,這樣我們先二分出一個串,點分治求出對應的 k 即可。
難點大概在於如何求出二分出的這個串,有這樣一個性質,你可以從所有串里隨機選一個串,因為是隨機,期望下的位置大概在中部,所以可以起到類似二分的效果。
我們可以用邊分治實現這個過程,大概更好寫一些。
HDU6566 【The Hanged Man】
這個男人講的非常好,建議看這個人的 https://www.cnblogs.com/lhm-/p/13697304.html
CF1270I Xor on Figures
大概是換了一個域的牛牛蹄。
重定義矩陣乘法為 \((a\times b)[x][y]=\otimes_i\otimes_j a[i][j]\times b[x-i][y-j]\) 下標是循環卷積類型的。
那么我們發現單位矩陣就是 \(I,I[0][0]=1\),我們的操作矩陣是 \(F[x_i][y_i]=1\),我們現在求一個矩陣 C,使得 \(F\times C=A\),C 的非零元素個數就是我們需要求得的答案。
如果 C 唯一不就是隨便做了?很棒的是:確實。
C 唯一類似於我們要證明 F 有逆元,然后 \(C = A \times F^{-1}\)。
我們探討這個矩陣乘法的一些性質:
定義加法為對應位異或。可以發現其具有:乘法分配率(對於元素由 0 / 1 組成)。
對於 F 來說,如果存在兩個逆元 \(FG_1=1,FG_2=1\),那么有 \(FG_1+FG_2=0\),有 \(FG=0\),其中 \(G \neq 0\),我們有另外一點發現:\(F^{2^k}=1\),那么 \(F^{2^k}G=0\) 得出 \(G=0\) 矛盾。
所以我們暴力對 \(A\) 乘上 \(F^{2^k-1}\) 即可。
無題
求解 \(\frac 1x + \frac 1y=\frac 1n\) 的 x, y 個數,其中 \(x,y \le 10^{12}\)
令 \(d=(x,y),x=da,y=db\),我們有 \(da+db\mid d^2ab\) 也就是 \(a+b\mid dab\)
可以理解為 a + b 中的質因子來源於 \(d,a,b\) 三處,不可能來源於 a,b,所以說 \(a+b \mid d\)。
計算式子(來源網絡)
[十二省聯考2019]字符串問題
碼農題,發現原題就是這樣一個東西,A 串和 B 串都看成點,A 串向和他有支配關系的 B 串連邊,B 串向滿足 B 是 A 前綴的 A 串連邊,然后跑最長路即可。
問題的難點大概在於連邊(其實是寫代碼),80 分就是先把串翻一翻,然后把后綴自動機建出來,倍增到對應節點利用后綴自動機直接建圖即可,100 分就是再后綴自動機上開 vector,然后前綴和建圖,聽起來是不是非常簡單,試看看吧!
[BJWC2018]Border 的四種求法
子串周期查詢,給定一個串,每次詢問一個子串的最長 border。
這里介紹一種點分治 + 后綴自動機 + 線段樹的做法。
字符串就想后綴自動機,對於詢問串 \(s[l,r]\),在后綴自動機上找到 \(r\) 所在的節點向上跳,我們需要找到滿足條件 \(p - len[Lca(p,ed[r])] + 1 \le l\) 和 \(p < r\) 最大的 \(p\)。
你可以暴力跳 + 線段樹查詢,這樣復雜度顯然是不對的。
考慮樹分治,這里我們選擇點分治來解決,設分治重心為 \(x\),因為是有根樹,我們分為上半部分和下半部分。
考慮下半部分對整體的貢獻,我們可以將下半部分所有的位置 \(u\) 插入到線段樹上,那么 \(u\) 和另一個點 \(v\) 的 \(LCA\) 就是 \(v\) 和 \(x\) 的 \(LCA\) (如果 \(u\),\(v\) 在同一子樹我們算的貢獻不會對答案產生影響,因為錯算的 \(len[LCA]\) 更小),現在我們就是預處理 p,然后枚舉 \(len[Lca(p,ed[r])]\),在線段樹上查滿足條件最大的 p 即可。
另外一方面,我們需要考慮上半部分對下半部分的貢獻,那么插入的時候順便枚舉 \(len[Lca(p,ed[r])]\),查詢的時候直接線段樹二分得到最大的 p 即可。
常數略大,但是空間達到了優秀的 \(\Theta(N\Sigma)\)
6300. 「CodePlus 2018 3 月賽」博弈論與概率統計
考慮對於一組詢問如何算出答案,容易發現答案的區間是 \([n - m, n]\)(如果 \(n \ge m\)),我們枚舉最終的答案是多少,比如令 \(k = n - m\),我們轉化到網格圖上(向上和向右)就發現是不經過 \(y = x - 1\) 這條線的方案數,在看看 \(k = n - m + 1\),發現就是經過 \(y = x - 1\) 而不經過 \(y = x - 2\) 的方案數,依次類推,我們可以用組合數輕松表示,然后相鄰兩項發現可以消一下,最后的形式如 \(\sum_{i=0}^k {n + m\choose k}\) 這個東西可以用莫隊來求,因為相鄰兩行可以遞推,相鄰兩列也可以遞推!
「BalkanOI 2018 Day1」Election
小清新有趣題,誰能想到竟然是最大子段和呢?
考慮這樣一種簡單的貪心,我們從前向后掃一遍,如果前綴小於 0 就刪掉當前字符,在從后向前掃一遍即可。
直接想不好導出正解,我們需要推式子形式化的說明,先做從前向后的貪心,設原先前綴和和后綴和數組為 \(pre_p,suf_p\),那么刪掉的個數就是 \(-\min pre_p\),考慮現在某個位置的后綴和 $ suf_p'$ 是多少,答案是 \(suf_p+(-\min pre + \min_{q < p} pre_q)\),所以我們最終的答案就是 \(- \min pre - \min suf'= -\min(suf_p+ \min_{q < p} pre_q)=-\min(pre_q+suf_p) \quad(q < p)\)
我們再加上總和試試,那么就是求最大子段和了!!然后用數據結構維護即可。