省选晚上的 AGC,今天 vp 了一下,拿到了大众题数 ABCD。EF 题等我有时间再说吧。
目前进度 4/6。
A - Takahashikun, The Strider
answer = 360 / gcd(X, 360)
B - Extension
被这道 sb 题卡了,把 C 题切了过后回来才知道咋做。
第一想法:定义 f(i, j) 表示现在已有 i 行 j 列的方案数,枚举下一次填行/列。
为了避免算重,考虑怎么唯一生成一种方案:尽量先扩展行,再扩展列。
也就是说,扩展一连串列过后必须紧接扩展一行,且这一行必须在最新的列里填黑。
对应到 f(i, j) 的转移:
(1)扩展行:(f(i-1,j) imes j)
(2)扩展列:(sum_{k<j} f(i-1, k) imes (i-1)^{j-k})
初值为 (f(A, B) = 1);最后答案为 (sum_{i=1}^{D} f(C,i) imes C^{D-i})。
时间复杂度 (O(n^3)),随手优化一下 (O(n^2))。
C - Shift
转化一下操作:设有 m 个 0,将序列分成 m + 1 段,第 i 段有 ai 个 1。
则操作等价于选择 i < j,ai++,aj--(aj > 0)。
从后往前 dp,定义 (f(i, j, k)) 表示处理到第 i 位,后面减了 j 次,当前总操作次数是 k。
枚举当前位最终状态是增加还是减少(注意不能考虑过程中的先增后减/先减后增,不然会算重)进行转移。
看起来是 (O(m imes|S|^3))。
冷静分析一下发现 1 的总数只有 (O(|S|)) 个,如果我们每次 k 只取 (sum_{p>i} a_p),则总复杂度是 (O(|S|^3))。
update in 2020/07/02:经评论提醒,这部分复杂度分析的关键在于,转移时枚举减少量的总量为 (sum a_i = O(|S|)),因此分析出来是 (O(|S|^3))。
上面那种证明并不是本质问题所在(虽然看着很有道理)。
D - Secret Passage
记 (f(i, x, y)) 表示后 i 位固定,有 x 个自由的 0,有 y 个自由的 1,是否合法。
初始值 (f(n, 0, 0) = 1),转移时枚举前两个是 0/1/2 个自由 0/1。
为了避免算重,如果 (f(i, x, y)) 对应的方案严格包含 (f(j, x', y'))(显然有 (j > i)),则最后将 (f(j, x', y')) 置为不合法。
记 (g(i,x, y)) 表示后 i 位固定,有 x 个自由的 0,有 y 个自由的 1,能够组合出的方案数。
边界状态 (g(0, x, y) = inom{x+y}{x})。
后 i 位构成的串一定是生成串的子序列,因此仿照子序列匹配的过程进行 dp 即可。
最后答案显然为 (sum f(i, x, y) imes g(i, x, y))。
E - Permutation Cover
下次一定。
F - Forbidden Tournament
下次一定。