Day1 T1 任务
Description
给出一张无边权有向图(n<=10000),要求在有向图中确定不同的4个点A,B,C,D,使A->B,B->C,C->D的路径都走最短路,求A->D的最长路。
Solution
首先题目看清(我看成无向图了)
由于无边权,可以\(O(n^2)\)得到点对互相的最短路。(我还傻傻的用floyd去去求)
然后\(O(n^2)\)枚举B,C两个点,分别求出距离B,C最远的点A(A要用反转有向图去求),D。为了避免A,D是一样的或者A,D和C,D一样,最好取前三远的点。然后由于只有九种情况,为了减少判断的失误,一一枚举加验证即可。
Day1 T2 子序列
Description
给出字符串S,求将字符串S扩展至N位字符串Q的种类,即S是Q的子序列。
Solution
不知道为什么,字符串\(S\)的内容是无关紧要的,只需要知道它的长度\(l\)。
我们将\(l\)位字符串扩展成\(k\)位字符串,总共扩展方法是
\[\sum_{l \leq i \leq k} C_{i-1}^{l-1} \times 25^{n-i} \times 26^{k-i}\]
Day1 T3 旅行机器人
Description
给出树,分别求所有节点当成根节点,到达任意叶子节点都只经过偶数个黑色节点的黑白染色方案。
Solution
我们发现,在定根节点的情况下,无论非叶子节点怎样染色,都有且仅有一满足条件的染色,这时叶子节点的黑白都根据非叶子节点的染色而决定了。即叶子节点的颜色根据上面进行微调。如果在到叶子之前只经过奇数个点,叶子就染成黑色,反之同理。所以染色方案数等于\(2^{非叶子节点个数}\).
为了快速计算所有节点作根节点的情况,我们发现总方案数\(\sum 2^{总节点个数-叶子节点个数}\)
而叶子结点个数为所有度为1的节点个数减去根度为1的特殊情况。因此算出度为1的节点个数Q,枚举根节点,如果该根度为1则叶子数为\(Q-1\),累加即可.
Day2 T1 发放纪念衫
衣服有N个尺码,有Ai个人是尺码i,有Bi个人是尺码i或i+1(即两者皆可).求至少要准备多少件衣服使得在这些人里任意选出k个,衣服都充足。
Solution
设尺码为i衣服数量为\(e_i\)
,则解为满足以下所有约束条件的最优解:
\[ \forall i,j \qquad min(\sum_{i \leq t \leq j} a_t + \sum_{i \leq t \leq j-1} b_t , k) \leq \sum_{i \leq t \leq j} e_t\]
贪心让所有\(e_i\)尽量小,可证明整体和\(S\)最小 : 若\(e_i+1\), 为达到最优解,
first
t1 >= min(a1,k)
t1+t2 >= min(a1+a2+b1,k)
t2 >= min(a2,k)
\[t_i = max(min(ai,k) , min(ai+ai-1+bi-1,k)-ti-1 , min(ai+ai-1+ai-2,bi-1+bi-2,k)-ti-1-ti-2)\]
\(O(n^2)\) (70)
Day2 T2 材料运输
给出一个树,求所有三元组\(\)个数使得a->w与c->w存在不相交的路径。
并且加Q条边,加完一条边求新的个数。
Solution
我只写了二十分的不加边情况,我以为加边以后变成图了就不能算了。
首先考虑不加边的情况:对于一个节点,作为三元组的w的方案总数是\(\sum sub[i] \times (n-1-sub[i])\)
sub[i]代表i的子树的元素个数。 这里把i的祖先以及兄弟们(即非子树中的点)也当成一棵子树。
把i当成根节点考虑,公式的意义是首先三元组中a,c点不能在i的同一子树中。否则一定有i连至子树的那条边重复。
所以a在一个子树中时,c可以在其他任意子树中。 公式就出来了。
然后可以公式变形
\(\sum sub[i] \times (n-1-sub[i]) = \sum sub[i] \times (n-1)- \sum sub^2[i]) = (n-1)^2 - \sum sub^2[i]\)
所以预处理出\(sup[i] = \sum sub^2[i]就行了\)
这样得到了20分方法。
然后加边以后情况会怎样呢。
我们发现加边以后就变成了一个环。我们发现在环上的点为w的方案数都是一样的。都是可以在环上取其它至多两个点或者在环以外的子树取点,即将这个环看成一个点然后用原来的方法求出解。所以将该环缩成点。并算出该环中点的数目,算出与之前的方案数变化量即可。
(当然有点复杂,70分的方法是缩点以后重新计算)
Day2 T3 错误算法
给出一种求一个1..n排列的逆序对数量的错误算法。即对于第i位,如果i>p[i], sum += i-p[i]. 最后的sum是答案。
给出n并且已知排列的前k位,求sum等于真实逆序对个数的排列个数。
Solution
首先我们要理清错误算法的思路。首先对于第i位如果为p[i]且i>p[i],那么第i位前面有i-1个数,小于p[i]的只有p[i]-1个数,说明前i-1位至少有i-p[i]个数是大于p[i]的,即产生逆序对。然而这漏了这样的情况:
- 当i<=p[i]时,前i-1个数中比p[i]大的数构成的逆序对。
- 当i>p[i]时,前i-1个数中比p[i]小的数不全出现增加的逆序对。
由于统计数相等,所以要避免以上情况,即: - 当i<=p[i]时,前i-1个数全部小于p[i]。
当i>p[i]时,前i-1个数比p[i]小的数全部出现。
Day3 T1 分数
给出n,求\(\frac{1}{x} + \frac{1}{y} = \frac{1}{n}\)的正整数解(x,y)个数。
Solution
唯一一道自行AC的简单题。
首先,\(x = \frac{ny}{y-n}\)
由于x,y都大于0,所以\(\frac{ny}{y-n}\geq 0 , y \geq 0\)
设\(k = y-n\) , 所以\(x = \frac{ny}{y-n} = \frac{(n+k)n}{k} = n + \frac{n^2}{k}\)
\(k = y-n \geq 1\)
因此答案为\(n^2的因子个数\)Day3 T2 数字分割
给出一个数字串,要求分割成多个数字(数字的第一位不能是0),且分割的数字严格递增。求分割的种类。
Solution
很容易想到计数DP.
我用的DP状态F[i][j]是最后一个数从第i位到第j位的种类.
状态转移是\(F[i][j] = \sum F[k][i-1] if number(k,i-1) < number(i,j)\)
number(k,i-1) < number(i,j)的情况有两种。
- \(i-1-k < j-i\) 即 \(k > 2i-j-1\)
\(i-1-k = j-i\) 时,即长度相等时,可以\(O(n^2)\)预处理字符串LCP,就可以\(O(1)\)比较了
由于第一种情况是一段连续的区间,于是可以前缀和优化,无奈考场优化写炸了。Day3 T3 超级图灵机
Description
给出一个定长图灵机的操作序列,指针初始在任意位置,存在四个操作:
- '<' 指针左移
- '>' 指针右移
- '0' 将该位覆盖成0
'1' 将该位覆盖成1
且操作不可能是非法的。
并给出这个图灵机在某一时刻的状态S,求有多少种原始状态。Solution
首先在指针位置固定的情况下,修改的位会越来越多。而当修改的这些位与S完全契合时,就是合法情况。而我们发现修改的这些位以前的状态都被覆盖了,所以初始是什么都可以。然后如果再一次出现与S完全契合的情况,由于修改的位越来越多,所以初始的情况包括了上一次的所有情况。因此只要记录最后一次就行了。
因此,我们在指针固定时得到了“自由”位的集合。
即指针在i时,集合Ai里的元素初始值任意,所以状态数\(S_i = 2^{|Ai|}\)。
但由于Ai和Aj里的元素可能会重叠,就会有冗余。
Ai和Aj的冗余个数是\(S_r = 2^{|A_i\cap A_j|}\)
所以我们考虑对于所有A集合做一次容斥。即可。