20190708B组
T1:30(30)
赛时:
这一道题一眼看去,就像一道数学的排列组合。
于是,大概手推了1个小时后,还没退出便放弃,打了个全排列暴力骗30分。
赛后:
又继续手推了很久,还是推不出。
废了便看了看题解。
考虑由所有与 S 有 k 处不同的字符串组成的一棵 Trie, 只需要在 Trie 上走出 T 这个串, 然后统计每一步排在它之前的子树大小之和就可以了。
k 记录后 n − i + 1 位还需要与 S 不同的位数。对于第 i 位,前 i − 1 位与 T 相同,第 i 位是 c < T[i] 且 c S[i] 的字符串共有 个,第 i 位是 c = S[i] 且 c < T[i] 的字符串共有 个。若 S[i] T[i], 就将 k 减去 1,一直计算到字符串结束就可 以了。
复杂度 O(n)
算法:
排列组合&乘法逆元
T2:60(60)
赛时:
看到这题时,脑海里浮现出来的就是gcd。
可是调了很久没调出,便先打了个60分的暴力。
比赛后段一直在调,可总调不出。
赛后:
想起了欧拉,便稍加修改了一下AC。
首先对于一个人 i, 显而易见,他所能到达的格子一定是 gcd(ai , n) 的倍数。
只要枚举 n 的约数,令当前枚举到的数为 d, 若存在一个 i, 使得 gcd(ai , n)|d 说明所有 gcd(i, n) = d 的格子都能被到达,答案加上 即可。
算法:
欧拉gcd
T3:10(100)
赛时:
一眼望去,这道题很想树形dp。
便很快便码了出来,样例和自己出的数据都过了。
自信满满的交了。
可是不知为何只有10分。
自己出的数据太水了,动态转移方程列错了。
赛后:
看了看正确的动态转移方程,才知赛时的自信是错的。
考虑改变 DP 方程的意义。使用一个 DF S 的过程进行 DP, fi,j 表示,在当前已经结束 了 DF S 的所有结点中选择 j 个,所能获得的最大收益。DF S 一个儿子前,将父亲的 f 值直 接复制给儿子,儿子的 DF S 结束后,再合并入父亲的 DF S 值,这里的 fson,∗ 是不包含结点 son 的情况的,因此将儿子 son 的情况并入 i 时,强制选择 son 上的物品。
fi,j = max{fi,j , fson,j−1 + valson}
复杂度 O(nlim)
算法:
树形dp