浙江財經大學第十四屆程序設計競賽題解
【題面pdf下載】鏈接: https://pan.baidu.com/s/1Eb16fHtNYMLrRk9QnXWa-g 密碼: dwn8
【題目牛客網提交鏈接】
【現場賽排名】鏈接: https://pan.baidu.com/s/1jfzH6-7BoPhEjnijGQK53w 密碼: y669
感謝各位大佬的參賽。
由於命題人水平不高,而且之前沒有命題經驗,又是第一次把題目放到外網,所以可能會有數據不嚴謹的情況出現;也有可能出題人對問題理解不深刻,沒想到最優解。如果發現了題目中的各種問題,可以在各種ACM QQ群(例如ACFun、ACM貼吧群、牛客網群)進行交流學習,也可以在這個博客留言。
Problem A. A Sad Story
先考慮求區間最大值和是最小值的情況:
證明:滿足最大值和是最小值時的多個序列中,必定有一種序列的最大值在序列兩端。
一個序列中拿出其最大值,對剩下的所有數的任意排列中,插入這個最大值。
當這個最大值排在兩端時,原序列區間最大值和加上這最大值。
當這個最大值不在兩端時,原序列區間最大值和加上這最大值,以及加上因這最大值加入而改變的區間最大值的差值(此時區間最大值一定不小於原區間最大值)。
例子:
$K$ 為 $3$ 。
$1$ $5$ $3$ $2$ $4$ 加入 $6$ 。
$1$ $5$ $3$ $2$ $6$ $4$ 為 $5 + 5 + 6 + 6$
不在兩端的最大值多了改變大小的區間最大值 $6 - 4$
這個結論對任意排列的序列都成立,因此所有區間最大值和是最小值的序列中,存在最大值在序列兩端的序列。
可得:
當序列為 V 字型時,一定是區間最大值和是最小值。
同理可得:
當序列為 Λ 字型時,一定是區間最小值和是最大值。
綜合得:
當序列為單調序列時,一定是區間最大值減最小值和的最小值。
單組數據時間復雜度 $O(NlogN)$。
Problem B. Bazinga
如果 $x$ 和 $k$ 互質,那麽 $x$ mod $k$ 和 $k$ 也互質。
以及 $(x + k * 1) * (x + k * 2) * (x + k * 3) * ... * (x + k * p) \equiv x^p$ (mod $k$) 。
把 $[1, k-1]$ 中與 $k$ 互質的數相乘,得到一個循環節對答案的貢獻,再對其在 $[l, r]$ 中出現的次數做快速冪計算。
再把之前 $[l, r]$ 不在循環節內的數暴力跑一遍乘進答案。
註意點:
- $k$ 為 $1$ 時,答案為 $0$。
單組數據時間復雜度 $O(K)$。
Problem C. Collect Jewel
性質1(雖然這個性質對解題好像沒啥用):在最優解中,每一個士兵在行走過程中,身上的價值是不可能變負的。
性質2(雖然這個性質對解題好像也沒啥用):在最優解中,一個士兵的路線終點,不可能是另一個士兵路線的起點。
性質3(雖然這個性質對解題好像又沒啥用):派出 $K$ 個士兵一定能得到最優解。
正題:
這是一個很容易察覺到的最 x 費用最大流問題。
由於每個節點能獲得至多 $1$ 次價值,第二個人再次走過這個節點,就無法獲得這個價值,因此需要拆點,每一個節點 $i$ 拆成兩個 $2i+1$ 和 $2i+2$,建立如下邊 $(2i+1,2i+2,1,V_i)$ 以及 $(2i+1,2i+2,inf,0)$。
對於原圖中每一條有向邊 $\left< x,y \right> $,建立如下邊 $(2x+2,2y+1,inf,-C_i)$。
建立超級原點$S$,建立$(S, 2i+1, inf, 0)$。
建立超級匯點$T$,建立$(2i+2,T,inf,0)$。
控制一下 $S$ 出去的流量最多為 $K$,跑一個最大費用最大流即可。可以把每條邊權取反之後求最小費用最大流,其中最小費用的絕對值就是答案。
註意:題目中數據範圍保證了 $U_i<V_i$ ,因此圖是有向無環圖,建完圖的網絡是不存在負環的。
單組數據時間復雜度 $O(min(K,N)NM)$。
這題如果不保證 $U_i<V_i$,就需要消負圈,如果有大佬會搞,望不吝賜教,看到網上很多都是一句話帶過,例如“強制把負圈滿流”,zkw 博客好像也沒給出代碼,還發現了一個題 POJ 2175。
Problem D. Disport with Jelly
可以這樣考慮:問題等價於有兩堆石頭,第一堆有 $K-L$ 個,第二堆有 $R-K$ 個,每人每次可以從任意一堆中取任意個,取走最後一個石頭的人算贏。這就是經典的 Nim 取子遊戲,看兩堆石頭異或值即可。由於這裏只有兩堆石頭,也可以判斷兩堆石頭數量是否相等。
單組數據時間復雜度 $O(1)$。
Problem E. Easygoing Single Tune Circulation
簡單地說題意就是,一個字典庫有 $N$ 個字符串,每個字符串中無重復字符,每個字符串以輸入作為最小周期無限循環。
有 $Q$ 次詢問,每次詢問一個字符串是否是 $N$ 個串中其中一個的子串。
由於字典庫中每個字符串都是無限循環的,所以對於每個詢問的串,也必須是循環的,不循環的就無解。例如[abcd],[aba],[abab]都被認為是循環的,第一個循環節是本身,第二,三兩個循環節均為[ab];而[abb],[abcdc]被認為不循環。
也就是說循環節要麽沒有,要麽就是從第 $0$ 個字符開始到第一個出現重復字符的前一個位置結束。(因為 $S_i$ 中無重復字符)
【1】對於每一個詢問,我們首先可以判定一下這個詢問串是否是字典庫中某個串兩倍的子串。如果找到就有解。這裏可以搞個廣義 SAM,每個子串都必然包含在 SAM 的某個狀態裏。
【2】如果沒有找到,就需要去尋找這次詢問的串的循環節是否可以由字典庫中某個串通過循環同構得到。可以將每一個 $S_i$ 的最小表示法插入字典樹,詢問的時候,可以把循環節也轉成最小表示法,然後去字典樹中找一找。
下面這種做法也放過去了:
把每一個 $S_i$ 及其循環同構的串都插入到字典樹中,然後兩種都可以查詢了。
各種 hash 算法不知道能不能過,造數據的時候卡了少數常見 base 和 mod,然後卡了一些雙 hash 超時。
Problem F. Formula One
枚舉兩輛車 $i$ 和 $j$,計算這兩輛車的超車次數。
兩輛車第一次相遇的時候,必然是快車比慢車多開了一圈,依據這個性質,可以計算出輛車第一次相遇的時間。兩車相鄰兩次相遇的時間間隔是不會變的。
相遇一次超車一次,剛好在停止的時候相遇就不算超車。
公式 $\left\lfloor \frac { P\times \left| { A }_{ i }-{ A }_{ j } \right| -1 }{ { A }_{ i }\times { A }_{ j } } \right\rfloor$
其中 $R$ 是可以不用的。
註意點:
- 精度問題,最好用整型計算
- $P$ 時刻剛好相遇不算超車
單組數據時間復雜度 $O(n^2)$。
Problem G. Get the Highest Score
首先有兩個貪心思想:
- 連續的一段 $-1$ 肯定需要填同一種數。
- 連續的一段 $-1$ 的左邊和右邊是同一種數字,那麽這段 $-1$ 就填那個數。
上述兩步填完後,按照題目中的方法壓縮數組。
然後這樣考慮:最後肯定有一段數字是相同的,也就是枚舉位置 $x$,讓 $val[1,n]= max(val[1, x] + (n-x)^2)$ 最大,枚舉過程中保證 $[x+1,n]$ 可以變成相同的數字。$val[1, x]$ 的最大值也是如此求解。
因此從左到右 dp ,記錄前綴能獲得的最大分數。可以發現,壓縮後的數組,最後一段相同的不會超過三小段。
單組數據時間復雜度 $O(n)$。
Problem H. Hero
按照 $A$ 是小於 $0$,還是等於 $0$,還是大於 $0$,將物品分成三類。
在同一類中:
以 $B$ 從小到大排序。先考慮 $B_{x}$ 左邊對其的影響,會發現有決策單調性(證明如下),右邊用同樣的方法處理。
$B_{i} < B_{j} < B_{y} < B_{x} < B_{z}$
若 $|A_{i}| \ge |A_{j}|$,$|A_{j}|$ 就可以不考慮,剩下就是單調遞增的 $|A|$ 。
證明:
當 $B_{x}$ 在 $i$ 取到最優解。
$|A_{i}|*|A_{x}|*(B_{x}-B_{i})^2 > |A_{j}|*|A_{x}|*(B_{x}-B_{j})^2 $ 得
$B_{x}-B_{j} < \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } +\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
$B_{x}-B_{j} > 0 > \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } -\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| }$
$0 < B_{y}-B_{j} < B_{x}-B_{j} < \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } +\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
因此 $B_{y}$ 一定不在 $j$ 取到最優解,故 $B_{y}$ 在 $i$ 或之前取到最優解。
當 $B_{x}$ 在 $j$ 取到最優解。
$|A_{i}|*|A_{x}|*(B_{x}-B_{i})^2 < |A_{j}|*|A_{x}|*(B_{x}-B_{j})^2 $ 得
$B_{x}-B_{j} > \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } +\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
$B_{x}-B_{j} < \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } -\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| } < 0$ 不用考慮
$B_{z}-B_{j} > B_{x}-B_{j} > \frac { \left( { B }_{ j }-{ B }_{ i } \right) \times \sqrt { |{ A }_{ i }| } \times \left( \sqrt { |{ A }_{ j }| } +\sqrt { |{ A }_{ i }| } \right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
因此 $B_{z}$ 一定不在 $i$ 取到最優解,故 $B_{z}$ 在 $j$ 或之後取到最優解。
剩下就用決策單調性就可以來做了。
單組數據時間復雜度 $O(nlogn)$。
Problem I. Interesting Set
這題思路很直白,先求出 $N$ 是第幾個,可以用很多方法求出是第 $P$ 個,然後判斷下 $P+K$ 是否存在,存在則求出第 $P+K$ 個是誰。算的時候楊輝三角打個表,算一算方案數這種就可以了,也可以用數位 dp 的思路來做。
單組數據時間復雜度 $O(64)$。
Problem J. Journey
要求經過每個點恰好一次,每條邊恰好一次,只有一條鏈是滿足要求的,也就是只要判斷給出的圖是否是一條鏈即可。
註意點:
- 一條鏈加一個簡單環的圖
- 一個節點,沒有邊的圖
- 清空數組用了 memset 會超時
單組數據時間復雜度 $O(n+m)$。
Problem K. Keep Danding
不妨把一個詢問拆成兩個,計算出區間長度小於等於 $R$ 的方案數,以及小於等於 $L-1$ 的方案數,相減即可得到答案。
下面說明區間長度小於等於 $K$ 的方案數:
首先預處理出 $f[i]$,表示 $i$ 位置最遠能到達 $f[i]$ 位置,保證區間 $[i,f[i]]$ 無重復元素,容易發現 $f[i]$ 是非遞減的。
令 $g[i] = f[i] - i + 1$,表示區間長度。
對於一次詢問,我們可以把 $[L, R]$ 拆成兩段來計算方案數。
$[L, R - K]$: 考慮每一個位置作為區間左端點的方案數,就是求這段區間上 $g[i]$ 小於等於 $K$ 的數字的和,主席樹可以單 log 高效求解。線段樹上每個節點排個序,每個節點二分這種雙 log 做法在現場賽也是允許通過的。
$[R-K+1, R]$: 這個部分比較經典,二分 $f$ 數組。
Problem L. Limitless Matrix
這題絕對 不 是暴力!
當 $|K|$ 為素數或 $1$ 或 $0$ 時不可能有解。
當 $N$ 為 $1$ 時不可能有解。
當 $N$ 為 $2$ 時,只有 $K$ 為平方數有解, $2 \times 2$ 矩陣每個元素都是 $ \sqrt K$ 。
當 $N$ 為 $3$ 時,只有 $K$ 為立方數有解(證明如下), $3 \times 3$ 矩陣每個元素都是 $ \sqrt[3] K$ (也可以用其他的方法湊,不過 $ \sqrt[3] K$ 最方便)。
證明:$N$ 為 $3$ 時情況。
$\left[ \begin{matrix} a & b & c \\ d & e & f \\ g & h & i \end{matrix} \right] $
$(a \times b \times c) \times (d \times e \times f) \times (g \times h \times i) = K^3 = (a \times e \times i) \times (b \times e \times h) \times (c \times e \times g)$
$d \times e \times f = e \times e \times e$
$K$ 為矩陣中間數 $e$ 的立方。
當 $N > 3$ 時,放心大膽的用 dfs 搜一遍吧。
先把 $K$ 分解成 $a \times b$ ,此題就變成了在 $N \times N$ 這個矩陣中,填入 $a$ 與 $b$ 使每行每列以及兩個對角線上有且只有一個 $a$ 和一個 $b$ ,其余位置填入 $1$ 。
先枚舉 $a$ 與 $b$ 在兩個對角線上如何放置,然後逐行枚舉 $a$ 應該放哪一列,放完 $a$ 後逐行枚舉放 $b$。發現 $N$ 從 $4$ 到 $1000$ 都是相當快的能跑出答案。
如果有大佬有直接構造的方法,歡迎在 QQ 群裏提出。
這題復雜度 O(不知道)。
Problem M. Magical Water Cup
如果每杯水倒出的量都一樣且第一杯水能倒出,則答案為無窮。
否則,先分別計算出每杯水最多可以倒多少次。
除了第一杯水,其他的水如果入得比出的多包括等於則可以倒無窮次,否則就是$\left\lfloor \frac { A_{ i } }{ B_{ i }-B_{ i-1 } } \right\rfloor$次。
第一杯水是先出後入,先判斷能否倒出第一次,如果可以就倒出,然後就和另外的水杯一樣處理了;否則答案就是 0。
然後遍歷一遍找到次數最小且離第一杯最近的那杯水,它就是最後不能操作的位置。簡單計算即可得到答案
註意點:
- 第一杯水是先出後入要特判
- 數據超過int的範圍
單組數據時間復雜度 $O(n)$。
---
最後,再次感謝您的參賽,祝您前程似錦、夢想成真。
浙江財經大學第十四屆程序設計競賽題解