上海市大學生程序設計競賽 - 七月賽 題解

轉送門

A. 狗喫骨頭

\(a_n\) 表示還有 \(n\) 只狗準備去喫骨頭時骨頭的數量 \(a_m\) 就是我們要求的答案。
由題意可以得到遞推關係

\[(a_{i} -1)\frac {m-1} m = a_{i-1} \]

(\(-1\) 代表喫一根,\(\frac {m-1} m\) 代表喫一份),利用待定係數法,轉換爲指數數列

\[a_n + m - 1 = {m\over m-1} (a_{n-1} + m - 1) \]

\(b_n = a_n + m - 1\),即 \(b_n = {m\over m-1} b_{n-1}\),立即有

\[b_n = ({m\over m-1})^{n-1} b_1 \]

由於要滿足喫骨頭的規律,\(a_n\) 必須滿足 \(m | (a_n - 1)\),並且\(a_n,b_n\)必須是整數。

\(m>2\) 時,由於 \(m \perp (m-1)\) (i.e. \(m\)\(m-1\) 互質),因此爲了保證\(b_1\sim b_m\) 是整數,必須有 \(b_1 = K (m-1)^{m-1}\) 其中 \(K\) 是正整數。

此外,因爲最後一條狗也要能夠按照規律喫骨頭,因此 \(m|(a_1-1)\),代入\(a_1 = b_1 - m + 1\)

\[m \Big|\Big( K(m-1)^{m-1} - m \Big) \]

仍然由於\(m \perp (m-1)\),由 Bezout 定理,\(m|\gcd(K(m-1)^{m-1},m)\),因此最小的 \(K=m\)。故 \(b_1=m(m-1)^{m-1},b_m = ({m\over m-1})^{m-1}b_1 =m^m\)

代入式子,\(a_m = b_m - m + 1 = m^m - m + 1\)。當\(m=2\)時,遞推式由於不成立,這是因爲 \(a_2 = 3\) 會導致第二隻狗沒有足夠的骨頭喫,上述推導沒有考慮"剩下的骨頭非負"這一要求。

因此答案爲

\[\begin{cases} m^m - m + 1 & m > 2 \\\\ 3 & m = 2 \end{cases} \]

注意邊界情況啊,少年

音樂之城

先考慮 \(t = 0\) 的情況,此時最長的 combo 數量是 \(b_i = a_i \% x\) 的最常連續相同子段。

\(s\) 表示啓動時間,不妨假設 \(s<0\),那麼一個音符能夠被擊打到,當且僅當 \(\exists y. |y|\le t \land a_i + y \equiv s \mod x\)。那麼通過枚舉 \(y\) 就能計算出 \(s \mod x\) 的值,那麼便求得了一個音符對應的能夠被擊打的 \(s\) 的集合,設爲 \(I_i\)。由於\(|I_i|\le 64\),那麼可以用狀態壓縮至一個 64 位數,記爲E[i]

那麼一段音符 \(l,l+1,\dots,r\) 能夠被擊打到,當且僅當 \(I_l \cap I_{l+1} \cap \dots \cap I_r \neq \varnothing\),這即當且僅當 \(E[i] \land E[i+1] \land \dots \land E[r] \neq 0\) (\(\land\) 表示二進制與)。因此可以通過預處理出 \(E\) 數組,並使用 st表維護區間 \(\land\) (二進制與) 。枚舉一個 \(l\),那麼就能夠通過二分查找最遠的 \(r\),使得 \(E[l] \land E[l+1] \land \dots \land E[r] \neq 0\),那麼 \([l,r]\) 就是一段 combo 區間。總複雜度 \(O(n \log n + {nx \over 64})\)

地球簽證

很明顯 \(i\)\(\lfloor \frac i 2 \rfloor\) 構成一顆二叉樹關係。 設 \(dp[i,a,b,0/1]\)表示考慮標號爲 \(i\) 的子樹,其中有 \(a\) 個被分爲"男性",\(b\)個被分爲"女性",且當前點被分爲男性/女性,的最大多樣性值。枚舉 \(i\) 的性別,然後枚舉 \(i\) 的兩個兒子的性別,就能夠得到轉移方程。

然而 \(a+b = \text{size}[i]\)\(\text{size}\) 表示子樹大小。因此只需要記錄一個維度即可。設 \(dp[i,a,0/1]\) 表示考慮標號爲 \(i\) 的子樹,其中有 \(a\) 個被分爲"男性",且當前點被分爲男性/女性,的最大多樣性值。那麼轉移方程爲,同樣枚舉 \(i\) 的性別,然後枚舉 \(i\) 的兩個兒子的性別,就能夠得到轉移方程。樹上揹包複雜度 \(O(n^2)\)

迴文文回

  • 結論1: 本質不同的迴文子串個數是 \(O(n)\) 的。
  • 結論2: 本質不同的迴文子串一定是以某個點結尾的、最長的那個迴文串。

證明:假設在原有字符串後面新加上一個字符長度變成 \(p\),那麼新產生的本質不同的迴文串一定是以 \(c\) 結尾的、最長的那個迴文串 \(S[l\ \dots\ p]\)。任何結尾於 \(p\),且長度短於 \(S[l\ \dots\ p]\) 的迴文串 \(S[l'\ \dots \ c]\),由對稱性,都可以在 \(S[l\ \dots\ p]\) 中找到一個相同的迴文串\(S[l\ \dots\ p'], p' = l + p - l'\),因此這個串重複出現過,不是新的"本質不同的串"。那麼長度爲 \(L\) 的迴文串,最多隻有 \(L\) 個本質不同的迴文串。

  • 結論3: 設總長度爲 \(N\),長度\(>\sqrt N\)的串的數量是 \(< \sqrt N\) 的。

證明:若長度 \(>\sqrt N\) 的字符串 \(\ge \sqrt N\),那麼本質不同的迴文串數量就會超過 \(\sqrt N \times \sqrt N = N\),與總長度爲 \(N\) 矛盾。

那麼用類似於 manacher 的算法處理迴文串,得到的 manacher 中的輔助數組 p[i], 可以用這個計算所有可能的本質不同的迴文子串,使用字符串哈希,將所有本質不同的子串的哈希值放入一個unordered_set(哈希) 中。考慮如何處理詢問,使用根號分治:

  • 詢問的兩個字符串的長度 \(\le \sqrt N\)時: 暴力詢問,一次詢問複雜度 \(O(\sqrt N)\)

  • 詢問的兩個字符串,一個長度 \(> \sqrt N\),一個 \(\le \sqrt N\)時:枚舉短串中所有的本質不同的字符串的哈希值,在長串的 unordered_set 中查詢是否存在相同迴文串。複雜度 \(O(\sqrt N)\)

  • 詢問的兩個字符串 \(A\)\(B\),兩者長度都 \(> \sqrt N\) 時:直接暴力枚舉 \(A\) 中所有本質不同的迴文串,在 \(B\) 串的 unordered_set 中查詢是否存在相同的迴文串。對於 \(A\) 中所有本質不同的迴文串,因此只會被拿出來"暴力匹配" \(\sqrt N\)次 (由結論3,只有 \(\sqrt N\) 種不同的 \(B\))。對於每個長字符串,只有\({N \over \sqrt N} = \sqrt N\)種查詢。因此對於每個長串所有本質不同的字符串,每個本質不同迴文串最多被拿出來暴力查詢\(\sqrt N\)次。由於總共只有\(O(N)\)長度的串,因此總共也只會有\(O(N\sqrt N)\)次查詢。

詢問的時候枚舉短串,然後把答案記憶化到 std::unordered_map 裏,就能AC。這不是數據水,而是複雜度正確

(使用迴文自動機可以避開字符串哈希,複雜度同樣爲\(O(N\sqrt N)\))

PS: 爲了卡掉複雜度不對的做法,造數據時想辦法卡滿了分塊的複雜度,導致一些大常數程序無法通過

研究方向

結論:一個研究方向 \((i,j,k)\) 可行,當且僅當 \(\gcd(j,k)|i\)

先假設我們只能進行一次操作(定義一次操作爲若干次 improve 後再 reduce),那麼 \(i\) 能化爲 \(j\) 當且僅當下列方程有解:

\[ j = {i + y k \over x} \quad (x>0 \land y \ge 0 \land x,y \in \mathbb{N}) \]

\[x j - y k = i \quad (x>0 \land y \ge 0 \land x,y \in \mathbb{N}) \]

由 Bezout 定理,這個方程如果要有解,必要條件是滿足 \(\gcd(j,k)|i\)。假設一組特解爲 \(x_0 j - y_0 k = i\)。由通解公式得 \(x=x_0 + kt,y = y_0 + jt\) 。 令 \(t\) 足夠大即得兩個正整數解。因此,如果只能進行一次操作(ie. 若干次 improve 再 reduce 一次),\((i,j,k)\) 可行當且僅當 \(\gcd(j,k)|i\)

綜上我們證明了,如果只能進行一次操作,那麼 \((i,j,k)\) 可行當且僅當 \(\gcd(j,k)|i\)。利用數學歸納法容易證明,如果可以進行 \(\forall K. K>1\) 次操作,那麼 \((i,j,k)\) 可行仍然當且僅當 \(\gcd(j,k)|i\)

因此

\[\begin{aligned} W &= \sum_{i=1}^n \sum_{j=1}^n \sum_{k=1}^n [\gcd(j,k)|i] \\ &= \sum_{i=1}^n \sum_{j=1}^n \sum_{k=1}^n \sum_{d=1}^{n} [\gcd(j,k) = d] [d | i] \\ &= \sum_{i=1}^n \sum_{d=1}^{n} [d | i] \sum_{j=1}^n \sum_{k=1}^n [\gcd(j,k) = d] \\ &= \sum_{i=1}^n \sum_{d=1}^{n} [d | i] \sum_{j=1}^n \sum_{k=1}^n [d|j][d|k][\gcd({j\over d},{k\over d}) = 1] \\ &= \sum_{i=1}^n \sum_{d=1}^{n} [d | i] \sum_{j=1}^{\lfloor \frac n d \rfloor} \sum_{k=1}^{\lfloor \frac n d \rfloor} [\gcd(j,k)=1] \\ &= \sum_{i=1}^n \sum_{d=1}^{n} [d | i] \Big(-1 + 2\sum_{j=1}^{\lfloor \frac n d \rfloor} \phi(j) \Big) \\ &= \sum_{d=1}^{n} \sum_{i=1}^n [d | i] \Big(-1 + 2\sum_{j=1}^{\lfloor \frac n d \rfloor} \phi(j) \Big) \\ &= \sum_{d=1}^n \lfloor \frac n d \rfloor \Big(-1 + 2\sum_{j=1}^{\lfloor \frac n d \rfloor} \phi(j) \Big) \\ \end{aligned} \]

利用數論分塊快速求上述式子,利用杜教篩等算法可以在 \(O(n^{2 \over 3})\) 的時間內計算一次 \(\sum_{i=1}^m \phi(i)\) 的前綴和;然而在本題中,所有需要用到的 \(\phi\) 的前綴和都在第一次杜教篩算法(ie. 計算 \(\sum_{i=1}^N \phi(i)\) , cf. oi-wiki )中計算過了,因此只需要一遍杜教篩,用map把計算過的值進行記憶化,避免重複計算。總複雜度 \(O(n^{2\over 3})\)

比賽情況

本次比賽中出現了比較多的小問題,比如輸入格式上下文不符、空格換行不分、題目描述不清、測試數據有誤等等。這些問題都是由於我們的疏忽導致的,在這裏向大家真誠道歉。

儘管我們在賽時採取了迅速有效的辦法進行補救(以上問題均在 \(120\) 秒內得到妥善解決),但是對比賽的影響還是不可避免的。希望能夠得到大家的諒解。尤其是對於較早遇到問題的同學,比如在"問答"中指出題目問題的同學等,請您聯繫我們,我們會盡可能以紀念品來向您表達歉意和感謝。

後記

感謝大家參加2023 年上海市大學生程序設計競賽 - 七月賽,希望大家能夠在比賽中有所收穫。如果有任何疑問,歡迎在討論區指正。如果你的做法更厲害或者有其他想吐槽或者討論的,歡迎在此處評論區,或者ShanghaiTech-ACM OJ指出。

鳴謝:上海交通大學俞勇老師、華東師範大學肖春芸老師、華東師範大學汪鼎尊同學、上海科技大學科道書院湯飛龍老師、信息學院屠可偉、楊思蓓、聞天明老師的大力協助。沒有你們本場場比賽難以順利進行。此外,感謝上海科技大學黃磊、曹宇涵同學,清華大學彭思進、高子翼同學,北京師範大學香港浸會大學聯合國際學院李欣澤同學和北京理工大學周行健同學對於本套試題的貢獻。此致,

敬禮!祝各位選手前程似錦!


上海科技大學程序設計競賽社團

地址:上海市浦東新區華夏中路393號上海科技大學信息學院 1B-205 室

郵箱: [email protected]

網址: acm.shanghaitech.edu.cn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章