AtCoder 瞎作

ARC 058

E - 和風いろはちゃん / Iroha and Haiku

題意

有一個長爲 \(n\) 的序列 \(a_0,a_1,\cdots, a_{n - 1}\) ,給你三個參數 \(X,Y,Z\)git

定義一個好的序列知足 存在 \(0\le x < y < z < w \le n\) 使得
\[ \begin{align} \sum_{i = x}^{y - 1} a_i &= X\\ \sum_{i = y}^{z - 1} a_i &= Y\\ \sum_{i = z}^{w - 1} a_i &= Z \end{align} \]
問知足條件的序列有多少個。(對於 \(10^9 + 7\) 取模)app

\(3 \le n \le 40, 1 \le X,Z \le 5, 1 \le Y \le 7\)\(1 \le a_i \le 10, a_i \in \mathbb{N^{+}}\)優化

題解

一道很妙的題qwqspa

一開始以爲是個思博題,而後發現怎麼正向計數都會算重。指針

後來去看了下題解,原來能夠轉化成 \(10^n -\) 不合法的序列數,這樣就不會記重了。code

但這樣轉化後如何記呢?數據範圍十分地小,能夠狀壓 \(dp\)htm

具體來講就是把一個 \(a_i\) 拆成一個 \(1\)\(a_i - 1\)\(0\)blog

好比 \(5\) 會被拆成 \(\underline{10000}\)排序

而後咱們就能夠把以前填的數順次拼起來了。

這樣有什麼好處呢?不難發現若是一段連續的和爲 \(S\) ,那麼 \(S\) 轉化後的集合 會是 連續一段轉化後拼起來構成的集合的 子集

好比 \(2 + 4 = 6\) ,就有 \(\underline {100000} \in \underline{10} + \underline{1000} = \underline{101000}\)

那麼咱們只要對於每一個位置狀壓前 \(X + Y + Z = 17\) 位就好了,一開始 \(X,Y,Z\) 壓成的狀態順次拼到一塊兒的狀態,就是全部不可行的狀態的本身。

枚舉當前填到哪一位,以及狀態,再枚舉這位填什麼就好了,複雜度就是 \(O(10n2^{X+Y+Z})\) 的。

技巧

要求連續和很小的時候也能夠巧妙狀壓,注意看數據範圍。

代碼

戳這個 連接 ,好寫的很。

ARC 059

F - バイナリハック / Unhappy Hacking

題意

一開始會有個空串 \(S\) ,有三個操做。

  • \(S\) 後面填個 \(0\)
  • \(S\) 後面填個 \(1\)
  • 刪去 \(S\) 的最後一個字符,若是 \(S\) 爲空,那麼不會改變。

而後你會進行 \(n\) 次操做,給你最後的串 \(S\) ,問有多少種不一樣的操做序列知足條件。(對於 \(10^9 + 7\) 取模)

\(n \le 5000, 1 \le |S| \le n\)

題解

一開始隨便想了個 \(O(n^3)\) 的暴力,就是令 dp[i][j][k] 爲當前進行了 \(i\) 次操做,串長爲 \(j\) ,第一個失配的地方在 \(k\) 的操做方案數,對於當前進行什麼操做分開考慮就好了。

其實正解很思博,咱們以前那個 dp 第三維是沒有必要的,由於咱們發現串的形態是不會影響答案的,因此就令 dp[i][j] 爲進行了 \(i\) 次操做,串長爲 \(j\) 的方案數。

最後答案就是 \(\displaystyle \frac{dp[n][len]}{2^{len}}\) ,由於最後每一個串對應的方案數都是同樣的,總共有 \(2^{len}\) 個串,這樣就是 \(O(n ^ 2)\) 的了。

其實能夠繼續優化,怎麼考慮計數呢,由於最後的串長要剛好爲 \(len\) ,咱們能夠轉化成至多爲 \(len\) 的答案減去至多爲 \(len - 1\) 的答案。

咱們假設 \(f(x)\) 爲串長至多爲 \(x\) 的答案,那麼表達出來就是:
\[ f(x) = \sum_{i = 0}^{n} [i - (n - i) \le x] ({n \choose i} - {n \choose i - (x + 1)}) \times 2^{i} \]
也就是咱們考慮在 \(n\) 個操做中有 \(i\) 個操做爲在後面添加字符,剩餘 \(n - i\) 個操做爲退格操做。

  • \([i - (n - i) \le x]\) 意味着全部退格和添加字符操做 所有抵消 後串長不超過 \(x\) ,這是必要的條件。

  • \(\displaystyle {n \choose i}\) 是全部可能添加和退格操做的排列,\(-\displaystyle {n \choose i - (x + 1)}\) 是全部最後串長會超過 \(x\) 的狀況。

    爲何會出現超過 \(x\) 的狀況呢?由於會有好一些退格操做都不會產生做用,不會產生做用的若是有 \(i - (x + 1)\) 及以上個,那麼就是不行的。

    不難發現,把其中不會消除的 \(i - (x + 1)\) 退格操做放在排列在 \(n\) 個總操做之中的任意一個地方,對應僅對應且僅對應一組不合法的解。

  • 最後發現每一個添加數字的操做會對應兩個操做,因此還要乘上 \(2^i\)

預處理了階乘和階乘逆元后就能夠作到 \(O(n)\) 的複雜度啦。

技巧

對於求最後要求形態惟一的題,能夠考慮有多少個形態的方案數是和它如出一轍的,最後除去那麼多就好了,一般能夠下降一維的複雜度。

代碼

\(O(n^3):\) 代碼戳這裏

\(O(n^2):\) 代碼戳這裏

\(O(n):\) 代碼戳這裏

ARC 060

D - 桁和 / Digit Sum

題意

給你兩個數 \(n, s\) ,找出一個最小的數 \(b\) 使得 \(n\)\(b\) 進制下的數位和爲 \(s\)

\(n,s \le {10}^{11}\)

題解

對於 \(< \sqrt n\)\(b\) 咱們能夠暴力枚舉,而後逐位拆解求和,複雜度是 \(O(\sqrt n \log n)\) 的。

對於 \([\lceil \sqrt n \rceil, n]\)\(b\) ,那麼 \(n\)\(b\) 進制下只有兩位,其實就是解一個以下的方程:
\[ \begin{align} \lfloor \frac{n}{b} \rfloor + n \bmod b &= s \\ \lfloor \frac{n}{b} \rfloor + (n - \lfloor \frac{n}{b} \rfloor \times b) &= s\\ \lfloor \frac{n}{b} \rfloor (1 - b) &= s - n \\ b &= \frac{n - S}{\lfloor \frac{n}{b} \rfloor} - 1 \end{align} \]
不難發現 \(\displaystyle \lfloor \frac{n}{b} \rfloor\) 只有 \(\sqrt n\) 種取值,咱們直接整除分塊,而後解方程便可。

而後對於 \(n = s\) 的點須要特判,\(b\) 此時爲 \(n + 1\)

因此最後複雜度是 \(O(\sqrt n \log n)\) 的。

技巧

對於進制下的題,要麼數位 \(dp\) ,要麼考慮分狀況討論。

\(\ge \lceil \sqrt n \rceil\) 的進制只會有兩位,\(< \lceil \sqrt n \rceil\) 的進制位也只有 \(\log n\) 層。

代碼

這裏

F - 最良表現 / Best Representation

題意

定義一個內部不包含循環子串 \(S\) 至少出現兩次的串爲好串,好比 \(\underline{a}\) 爲好串,\(\underline{abab}\) 不爲好串,\(\underline{cdcdc}\) 爲好串。

給你一個字符串 \(w\) ,如今要把它劃分紅不少段好串,其中段數要儘可能少。而後問段數儘可能上的前提下,問有多少種劃分方式。(對於 \(10^9 + 7\) 取模)

題解

假設最好最優的段數爲 \(l\)

判斷一個串是否爲好串能夠先用 \(kmp\) ,求出每一個前綴的 \(fail\) (也就是這個前綴的最長公共先後綴 \((border)\)

而後就能夠用一個經常使用性質了:

最小循環串(不必定會出現完畢)的長度等於 \(len - border\) ,具體證實能夠參考 這裏

而後它爲好串,當且僅當 \(fail_i\)\(0\) 或者 \(i \mod (fail_i - i) \not = 0\) 。前者由於最小循環串是本身自己,後者由於不能徹底填滿。

首先能夠特殊考慮兩種狀況:

  • \(l = |w|:\) 此時全部字母都是同樣的,能夠在最後判斷。
  • \(l = 1:\) 此時整個串可行,能夠直接判掉。

剩下的狀況其實答案都爲 \(l = 2\) ,爲何呢?

由於你能夠考慮把 \(1 \sim |w| - 1\) 分到一組,最後一個字母單獨分紅一組。

若是這樣不可行的話,只有兩種狀況:

  • 所有字母相等,前面會特判掉。
  • \(1 \sim |S| - 1\) 存在一個最小循環串 \(|S|\) 至少出現兩次,和最後一個拼起來後必定使得整個串不存在一個可行的最小循環串。

而後剩下計算方案數,只須要枚舉斷點,而後判斷先後綴是否爲好串便可。( \(kmp\) 預處理兩次就好了)

技巧

牢記 \(border(fail)\) 與 最小循環串 互相轉化的性質。

代碼

這裏

ARC 063

E - 木と整數 / Integers on a Tree

題意

給你一顆有 \(n\) 個點的樹,一開始有 \(k\) 個點有權值。問是否能讓其餘的點也賦上權值,使得相鄰兩個節點的權值差的絕對值爲 \(1\)

若是能夠,請給出一組構造方案知足條件。

\(1 \le k \le n \le 10^5\)

題解

首先分層考慮奇偶性是否存在解。

而後你對於每一個點維護它可取的權值範圍 \([l_i, r_i]\)

而後每次須要從兒子轉移上來:
\[ l_u = \max\{l_u, l_{son} - 1\}\\ r_u = \min\{r_u, r_{son} + 1\} \]
邊界就是,這個點無權值就是 \([- \infty, \infty]\) ,有權值就是 \([val_u, val_u]\)

若是 \(l_u > r_u\) 無解。

而後只須要從上往下隨意構造一組方案便可 。

技巧

樹上構造關於權值構造能夠考慮奇偶性。關於差值,能夠考慮每一個點的取值範圍而後向上轉移便可。

代碼

這裏

ARC 065

E - へんなコンパス / Manhattan Compass

題意

平面上有 \(n\) 個點,其中選出兩個點 \(a, b\) ,令他們之間的曼哈頓距離爲 \(D\)

兩個點聯通當且僅當這兩個點之間的曼哈頓距離也爲 \(D\) ,最後詢問 \(a\) 所在聯通塊的每一個點的度數之和。

\(1 \le n \le 10^5\)

題解

一道挺不錯的套路題。

看到曼哈頓距離不難想到能夠與切比雪夫距離進行轉換。

切比雪夫距離:

平面上兩點 \((x_1, y_1), (x_2, y_2)\) 之間的距離爲 \(\max(|x_1 - x_2|, |y_1 - y_2|)\)

如何轉換呢?考慮把原來座標系旋轉 \(45^{\circ}\) 。原來的座標 \((x, y)\) 就變成了 \((x + y, x - y)\)

而後原圖上兩點的曼哈頓距離就變成切比雪夫距離了。

來理性地證實一波:

假設原來兩點爲 \((x_1, y_1), (x_2, y_2)\) 變化後就是 \((x_1 + y_1, x_1 - y_1), (x_2 + y_2, x_2 - y_2)\)
\[ \begin{align} d_{\mathcal{Chebyshev}} &= \max{\{|(x_1+y_1) - (x_2 + y_2)|, |(x_1 - y_1) - (x_2 - y_2)|\}}\\ &=\max{\{|(x_1-x_2) + (y_1 - y_2)|, |(x_1 - x_2) - (y_1 - y_2)|\}}\\ &=\max{\{|(x_1-x_2) \pm (y_1 - y_2)|\}}\\ &=|x_1 - x_2| + |y_1- y_2| \end{align} \]
注意最後一步能夠本身討論兩邊的正負來證實。

而後轉了後,咱們就能夠轉化成對於兩個點其中一維的差值恰好爲 \(D\) ,另一維 \(\le D\)

爲了方便討論,咱們先假設 \(x\) 差值爲 \(D\) ,另外的一維也是同樣討論。
\[ \begin{cases} x_1 - x_2 = D\\ -D\le y_1 - y_2 \le D \end{cases} \]
咱們固定一維 \(x\) ,那麼另一維 \(y\) 就處於一個範圍內,咱們就能夠快速處理出一個點的度數爲多少了。

具體實現就是按 \(x\) 排序, \(x\) 相同按 \(y\) 排序,而後用兩個指針 \(l, r\) 維護當前的區間 \([l, r]\) 就好了。(由於區間是單調的)

可是連邊確定不能暴力連,但咱們發現是處於一段連續區間內,是否能夠線段樹優化建邊呢?是能夠的,但徹底沒有必要。

由於最後咱們只須要求聯通塊,只須要保證連通性不會變,那麼每次連邊的時候咱們發現相鄰的不須要重複連邊沒有意義,咱們每次記個 \(pos\) 表示當前連邊的區間掃到哪了就好了,而後這個點連向最後一個就好了。

這樣的話最後的邊數是 \(O(n)\) 的了,最後總複雜度是 \(O(n \log n)\) 的,瓶頸在排序上。

技巧

曼哈頓距離經常能和切比雪夫距離轉化,而後經常定下一維另一個就是個區間範圍,這樣就好處理不少了。

而後區間連通性連邊能夠用操做把邊數降到 \(O(n)\)

代碼

這裏,挺短的。

相關文章
相關標籤/搜索