A. 雙階乘
輸出 \(2021!! \bmod 10^4\)
for 循環每次減 \(2\) 即可
B. 格點
求第一象限整點中,\(xy\leq 2021\) 的整點個數
for 循環暴力遍歷 \(2021\times 2021\) 的平面,統計答案即可
C. 整數分解
求 \(2021\) 分解為 \(5\) 個正整數的有序分解方案數
令 \(f_{n, p}\) 表示 \(n\) 被分解為 \(p\) 個正整數的有序分解方案數
搜索或遞推均可
D. 城邦
給定編號為 \(1\)~\(2021\) 的 \(2021\) 元完全圖,定義點權為編號數碼的集合的元素和(例如 : \(2021\) 的為 \(2+0+1=3\))。
定義連接兩點 \(a, b\) 的邊權為兩點點權之和
求 MST 邊權和
先暴力把 \(1\)~\(2021\) 的點權跑出來,然后所有邊已知
由於是提交答案題,跑 Kruskal 或者 Prim 算法均可
E. 游戲
給定數值 \(n\) ,兩人輪流進行游戲。每一輪可將數字 \(n\) 化為其因數之一,直到 \(n\) 變為 \(1\)
問 \(n=20210509\) 時的游戲方案數
令 \(f_d\) 表示從 \(d\) 開始,游戲的方案數,初始 \(f_1=1\)
用刷表法,將 \(d\) 的所有倍數 \(n\) ,均執行 \(f_n+=f_d\)
復雜度為 \(\displaystyle \sum_{i=1}^n \lfloor{n\over i}\rfloor\approx \sum_{i=1}^n {n\over i}=O(n\log n)\)
期望時長為 \(5s\)
F. 小平方
求 \([1,n)\cap Z\) 中,模 \(n\) 意義下,平方嚴格小於 \({n\over 2}\) 的數的個數
\(n\leq 10^4\)
for 循環暴力驗證即可
G. 完全平方數
給定正整數 \(n\) ,求最小的正整數 \(x\) ,使得 \(nx\) 為完全平方數
\(n\leq 10^{12}\)
考慮到 \(n\) 大於 \(\sqrt n\) 的質因數最多 \(1\) 個
否則任意兩個乘起來也超過 \(n\)
因此優先用歐拉篩或埃氏篩打出 \(\sqrt n\leq 10^6\) 范圍內的質因數,將該部分的每個質數在 \(n\) 中的次數求出
若次數為奇數,則 \(x\) 中必須出現奇數次該質數,故取 \(1\) 次;否則 \(x\) 中需為偶數次,取 \(0\) 次
最后驗證 \(n\) 是否仍有其他質因數,若有,則 \(x\) 中該質因數必須出現奇數次,同樣取 \(1\) 次
H. 負載均衡
\(n\) 台計算機,第 \(i\) 台算力為 \(v_i\)
\(m\) 個任務,每個在 \(a_i\) 時刻送達,需要消耗 \(b_i\) 號計算機 \(c_i\) 的時間與 \(d_i\) 的算力
若分配任務時,計算機算力充足,必須執行任務,並輸出剩余算力;否則輸出 \(-1\)
\(n, m\leq 2\times 10^5\)
考慮將任務拆成兩瓣:
- \(a_i\) 時到達的,消耗 \(b_i\) 號計算機 \(d_i\) 算力的
- \(a_i+c_i\) 時到達的,消耗 \(b_i\) 號計算機 \(-d_i\) 算力的
且第二個子任務奏效當且僅當第一個子任務奏效
因此,對任務標記原來的序號 \(i\) ,再按時間排序;時間相同時,算力為負數的任務(第二類任務)優先
維護每台計算機的剩余算力,按時間順序執行任務
當執行第一類任務時,檢查算力是否充足,充足則執行當前任務,更新剩余算力並輸出;若不充足,則標記當前任務原來序號 \(i\) 不生效,並且輸出 \(-1\)
當執行第二類任務時,檢查當前任務是否生效,若不生效則直接退出;否則更新算力
復雜度為 \(O(n\log n)\)
I. 國際象棋
規定國際象棋棋盤中,位於點 \((x,y)\) 的馬可以攻擊 \(8\) 個方向:
- \((x-2, y-1)\)
- \((x-2, y+1)\)
- \((x-1, y-2)\)
- \((x-1, y+2)\)
- \((x+1, y-2)\)
- \((x+1, y+2)\)
- \((x+2, y-1)\)
- \((x+2, y+1)\)
求 \(n\times m\) 的棋盤中,放置 \(k\) 匹馬且不互相攻擊的方案數
\(n\leq 6, m\leq 100, k\leq 20\)
狀壓 dp :預處理 \(n_{1, S}\) 表示當前行狀態狀態為 \(S\) 時,下一行的最大可選集合;\(n_{2, S}\) 表示下兩行最大可選集合;\(cnt_S\) 表示 \(|S|\)
記 \(f_{m, S, T, k}\) 表示第 \(m\) 行狀態為 \(S\) 且第 \((m-1)\) 行狀態為 \(T\) 時,放置了 \(k\) 匹馬且不互相攻擊的方案數
不難得出,當且僅當 \(S\subseteq n_{1, T}\) 時方程有意義,且初始狀態為 \(f_{1, S, 0, cnt_S}=1\)
狀態轉移采用刷表實現:將 \(f_{m, S, T, k}\) 刷到 \(\forall R\subseteq (n_{1, S}\cap n_{2, T}),f_{m+1, R, S, k+|R|}\)
答案為 \(\displaystyle \sum_S\sum_T f_{m, S, T, k}\)
發現第一維可以滾動成 \(m\bmod 2\) 形式,故空間復雜度為 \(2\times 2^n\times 2^n\times k=O(k\cdot 4^n)\)
時間復雜度為 \(m\times 2^n\times 2^n\times k+2^n\times 2^n=O(mk\cdot 4^n)\) ,顯然充足
甚至加上了 \(S\subseteq n_{1, T}\) 的限制,根本拉不到那么大
J. 完美序列
這題題目是真的繞
定義完美序列為:滿足除第 \(1\) 個數外,所有數為前一個數的因數的序列。
定義序列的完美值為:該序列所有完美子序列的長度最大值
求 \(1\)~\(n\) 的所有排列 \(P\) 中,每個排列中,所有長度為 \(\{n, (n-1), (n-2), \cdots , 1\}\) 的完美值的完美序列,它們的元素和
\(T\leq 10^5\) 組獨立詢問,每次詢問 \(n\leq 10^6\)
當 \(n=3\) 時,\(\{3, 2, 1\}\) 的完美值為 \(\{2, 1\}\) 的長度 \(2\)
考慮 \(n=3\) 的所有排列:
- \(\{1,2,3\}\) 不含長度為 \(2\) 的完美序列
- \(\{1,3,2\}\) 不含長度為 \(2\) 的完美序列
- \(\{2,1,3\}\) 含長度為 \(2\) 的完美序列 \(\{2, 1\}\),元素和為 \(3\)
- \(\{2,3,1\}\) 含長度為 \(2\) 的完美序列 \(\{2, 1\}, \{3, 1\}\),元素和為 \(7\)
- \(\{3,1,2\}\) 含長度為 \(2\) 的完美序列 \(\{3, 1\}\),元素和為 \(4\)
- \(\{3,2,1\}\) 含長度為 \(2\) 的完美序列 \(\{2, 1\}, \{3, 1\}\),元素和為 \(7\)
故答案為 \(0+0+3+7+4+7=21\)
先考慮打出 \(f_n\) 表示嚴格以 \(n\) 開頭的完美子序列長度最大值,則有 \(\displaystyle f_n=\max_{d\mid n}f_d+1\)
因此,同上某題也是因數的,用刷表法算出 \(f_n\)
接着,根據定義,\(\{n, (n-1), (n-2), \cdots , 1\}\) 並沒有限制開頭值,故其完美值為 \(\displaystyle g_n=\max_{i=1}^n f_i\) ,動態刷前綴最大值更新即可
現考慮貢獻:設存在某個完美序列 \(v_{1, 2, 3, \cdots, g_n}\)
則元素和為 \(\displaystyle \sum_{i=1}^{g_n} v_i\),在所有排列中出現的方案數為 \(\displaystyle P(n, n-g_n)={n!\over g_n!}\),故貢獻為 \(\displaystyle (\sum_{i=1}^{g_n} v_i)\cdot {n!\over g_n!}\)
同時,對於另一個完美序列 \(w_{1, 2, 3, \cdots, g_n}\) ,貢獻同樣為 \(\displaystyle (\sum_{i=1}^{g_n} w_i)\cdot {n!\over g_n!}\) ,且和 \(v\) 的獨立
故需求出所有完美序列的所有元素和:\(A_n\) ,則答案為 \(A_n\cdot {n!\over g_n!}\)
現考慮如何求 \(A_n\) :
先記 \(c_n\) 表示 \(n\) 開頭的完美序列個數
刷表求 \(f_n\) 時,考慮由 \(f_d\) 更新 \(f_n\) 的一幕
當 \(f_d+1=f_n\) 時,說明 \(n\) 的后續接 \(d\) 是當前最優的策略之一,故更新 \(\begin{cases}A_n+=A_d+n\times c_d\\c_n+=c_d\end{cases}\)
當 \(f_d+1>f_n\) 時,說明 \(n\) 的后續接 \(d\) 比之前的都更優,故更新 \(f_n=f_d+1\) ,且 \(\begin{cases}A_n=A_d+n\\c_n=c_d\end{cases}\)
同理,后續刷表求 \(g_n\) 時,由於 \(g_n=\max(g_{n-1}, f_n)\)
當 \(g_{n-1}=f_n\) 時,說明以 \(n\) 開始和以某些比 \(n\) 小的數開始都是最優策略,故更新 \(\begin{cases}A_n+=A_{n-1}\\c_n+=c_{n-1}\end{cases}\)
當 \(g_{n-1}>f_n\) 時,說明不以 \(n\) 開始是最優策略,故更新 \(\begin{cases}A_n=A_{n-1}\\c_n=c_{n-1}\end{cases}\)
算法瓶頸在打出 \(A_n\) 與 \(g_n\) 以及階乘極其逆元,復雜度在於枚舉枚舉倍數的 \(O(n\log n)\) 和線性掃描的 \(O(n)\)
故總復雜度為 \(O(n\log n+T)\)
