2019年湖南省大學生計算機程序設計競賽 (HNCPC2019) 簡要題解
update10.01 突然發現叉姐把這場的題傳到牛客上了,現在大家可以有地方提交了呢。
不知道該干什么所以就來水一篇題解
題解全是根據印象口胡的,代碼是不可能重新寫的,這輩子不可能重新寫的。
A
description
有一個\(n\times m\)的全\(0\)矩陣,選擇一個子矩陣全部修改成\(1\),現在給出修改后的矩陣,問是否存在合法修改方案。
\(1 \le n, m \le 10.\)
solution
找到最左上的\(1\)和最右下的\(1\),判斷是否中間全是\(1\),剩下的全是\(0\)就好了。
需要特判沒有\(1\)的case。
B
description
給出\(n,k\),求\(\min(\binom{n}{k},10^{18})\)。
\(0 \le k \le n \le 10^9.\)
solution
gzy寫的,他一遍過了,反正gzynb就對了。
先令\(k\le \lfloor\frac n2\rfloor\),然后再\(O(k)\)計算組合數,即每次乘一個數再除一個數,可以用long double
或__int128
判斷是否超過\(10^{18}\),一旦爆了就直接輸出\(10^{18}\)。
C
description
給出一個長度為\(n\)的字符集大小為\(m\)的串,對於\(\forall i\in[1,m]\),求往字符串后面新增一個字符\(i\)后增加了多少本質不同的子串。
\(1 \le n,m \le 10^6.\)
solution
枚舉原串的一個后綴,找出這個后綴在串中的其他出現位置,此時可以更新這個位置往后一個字符對應的答案。
實現中可以使用后綴自動機(只要從自動機上原串對應的那個點出發一直跳\(fail\)就行了)或者exkmp(線性求原串與所有前綴的\(lcs\))。
D
description
求有多少長度為\(n\)的序列\(\{a_i\}\)滿足:
- \(a_i \in [0,9].\)
- 滿足\(m\)條限制,每條限制給出\(l,r\),要求\(\prod_{i=l}^ra_i \equiv 0 \bmod 9.\)
方案數對\(10^9+7\)取模。
\(1 \le n,m \le 50.\)
solution
限制即為要求區間內存在至少兩個\(3\)的質因子,在這里可以認為\(0\)包含\(\infty\)個\(3\)質因子。
記\(dp_{i,j,k}\)表示前\(i\)個位置,最近的兩個\(3\)質因子在\(j,k\)的方案數,轉移是先判掉不合法(對每個限制的右端點維護對應最大左端點),然后在考慮第\(i+1\)位上是填\(\{0,9\}\)還是\(\{3,6\}\)還是\(\{1,2,4,5,7,8\}\)。
E
description
給一個數字串\(S\),要求將\(S\)划分成若干互不相同的\([0,99]\)內的整數,不能含有前導零,求方案數。
\(1 \le |S| \le 50.\)
solution
直接搜。
考慮一位數(包括\(0\))只有\(10\)個,那么確定了一位數的位置后剩下的划分也就隨之確定了,假設數字\(i\)出現了\(a_i\)次,那么搜索的總狀態數不超過\(\prod_{i=0}^9(a_i+1) \le (\frac{\sum_{i=0}^9(a_i+1)}{10})^{10}=6^{10}\)。
F
description
一個人初始在\((0,0)\),可以走不超過\(n\)步,每一步可以向右走不超過\(a\)步,或者向上走不超過\(b\)步,或者向左走不超過\(c\)步,或者向下走不超過\(d\)步,求這個人可到達的位置數\(\bmod 10^9+7\)。
\(1 \le n,a,b,c,d \le 10^9.\)
solution
等差數列求和直接算就好了。
G
description
有一個\(n\times m\)的矩陣\(\{C_{ij}\}\),需要構造一個\(m\)階排列\(\sigma\),使得矩陣的所有列向量根據\(\sigma\)重新排列后滿足行向量字典序單調不降。要求輸出滿足條件的字典序最小的
\(1 \le n,m \le 2000.\)
solution
考慮\(n=2\),那么每一列的兩個數的大小關系只有以下三種:\(C_{1j}>C_{2j}\)或\(C_{1j}=C_{2j}\)或\(C_{1j}<C_{2j}\)。由於需要滿足第二行的字典序大於等於第一行,那么所有\(C_{1j}>C_{2j}\)的\(j\)都需要排在至少一個\(C_{1k}<C_{2k}\)的\(k\)后面。
這個限制可以抽象成:給出\(\{1,2,...,m\}\)的兩個子集\(A,B\),滿足\(A\cap B = \varnothing\),要求在最終的排列\(\sigma\)中,\(B\)中每個元素都至少排在一個\(A\)中元素的后面。
\(n>2\)的情況就是給出了多組\(A,B\)。
令每個點的入度為包含這個點的\(B\)集合數量,每次選擇一個入度為零且編號最小的點(保證字典序最小)放在當前排列末尾,如果這個元素在某些\(A\)集合內是第一次出現,那么就把這個\(A\)對應的\(B\)中所有元素的入度減\(1\)。
總時間復雜度\(O(nm+m\log m)\)。
H
description
一張\(n+m\)個點的圖,初始在\(1\)號點,每次在\(i\)號點的時候有\(P_{i,j}\)的概率走到\(j\)號點,保證\(\forall i\in[n+1,n+m],P_{i,j}=[i=j]\)。可以發現經過無限次行走后停留在前\(n\)號點上的概率是\(0\),求停留在后\(m\)號點每個點的概率\(\bmod 10^9+7\)。
\(1 \le n + m \le 500.\)
solution
設\(f_i\)表示經過\(i\)點的期望次數,於是
高斯消元解出\(f_i\)后隨便算一下就好了。
I
description
給一棵樹,邊有邊權,求有多少條路徑滿足邊權和是\(2019\)的倍數。
\(1 \le n \le 20000.\)
solution
點分即可。
J
description
給出\(n\)個\(m\)元組\((a_1,a_2,...,a_m)\),記\(count(x)\)表示有多少個\(m\)元組滿足\(\forall j\in[1,m],popcount(a_j\land x)\)為奇數。求\(\sum_{x=0}^{2^k-1}count(x)3^x \bmod 10^9+7\)。
\(1 \le n \le 10^4, 1 \le m \le 10, 1 \le k \le 30, 0 \le a_i < 2^k.\)
solution
對於每個\(n\)元組單獨求答案然后相加即為答案。
把\(m\)元組寫成一個\(k\times m\)的\(01\)矩陣,相當於選出一些行向量做異或運算,要求結果為\(2^m-1\)。直接按二進制位\(dp\),記\(f_{i,j}\)表示處理完前\(i\)位,當前二進制狀態為\(j(j\in[0,2^m))\)的方案數。
總復雜度是\(O(nk2^m)\),大概能過的樣子。
K
description
維護\(n\)個鏈表以及\(m\)次操作,每次操作為將一個鏈表剪切到另外一個的后邊並將其翻轉。
\(1 \le n,m \le 10^5.\)
solution
直接啟發式合並即可。
不過要我寫可能就直接上treap了。