NOI2015
寿司晚宴
-
这个题目和素数的数量关系很大
-
对于 30 分,一个想法就是直接状压下质数,\(dp[S_1][S_2]\) 表示小 G 选了 \(S_1\) ,小 w 选了 \(S_2\) 的方案数
-
枚举每个寿司选或不选,谁选,这个就很好转移,但是 100 分的质数就太大了,绝对是压不下来的
-
讲实话当时我有个想法,我发现很多大质数实际上用到的并不多,但是每个状态却都记录这一位,这就非常的浪费了,但是我觉得这没办法
-
但是实际上是有办法的,我们发现对于 \(n\leq 500\) 的数,不会出现大于 \(\sqrt{500}\) 的两个质数
-
那么我们将这个独特的质数,记录下来,对于剩下的小质数,只会有 8 个,所以可以直接状压
-
对于每个数,按照独特的质数的大小排序,这么做是为了将大质数一样的数放在一起,说明这一些数只能被一方取走
-
这一过程的转移和之前的转移时不一样的,所以我们对于每一个这样的段,都单独的转移
-
设 \(f_1[S_1][S_2],f_2[S_1][S_2]\) ,分别表示这一段数被第一/二个人取走的状态的方案数
-
一段开始前,先将 \(dp\) 赋值上去,一段转移完后,再用 \(f_1,f_2\) 赋值回 \(dp\)
-
\(dp[S_1][S_2]=f_1[S_1][S_2]+f_2[S_1][S_2]-dp[S_1][S_2]\)
-
后面的减法是因为每种状态没人选的情况被算了两次,所以要减掉
-
注意每次转移前要判断是否合法,就是 \(S_2,S_2\) 之间是否有冲突
-
时间复杂度为 \(O(n2^{16})\)
总结
-
状压 dp + 根号分治
-
算是一个小 trick,对于有关质数但是质数的个数很多,考虑根号一下
-
感觉还是比较简单的 SAM 板题,这里直接考虑第二问
-
首先对于反串建 SAM ,然后 dfs 一遍每个节点
-
因为有负数,所以要维护最大值和次大值和最小值和次小值
-
每个节点先让最长的长度取 \(\max\) ,最后再每个长度向后取 \(\max\) 就可以了 (不知道为什么题解一大堆人要用线段树,虽然我不知道这个套路之前也曾经想过线段树)
-
总的复杂度就是 \(O(n)\)
-
注意第一问的方案数不可以像第二问一样直接加上后面的,因为会算重的,所以老老实实的将区间的个数 +1
-
这里可以差分,最后前缀和一下就可以了
总结
- SAM 板题