为什么写这个题解呢,因为感觉真的很久都没有写过这种屎长代码了。
\(type=1\)
手画不难发现,如果一个序列有 \(\le 2\) 个颜色段,那么它的贡献是 \(0\),因为任意一个子序列都会是子段。
否则贡献是 \(n-2\),因为可以任意漏选中间颜色段的一个元素,时间复杂度 \(O(n)\)。
\(type=2\)
直觉上告诉我们,序列应该形如 \(S_0,x,S_1,x,S_2\),我们可以选择 \(S_0+x\) 或者 \(x+S_2\)。
这样应该是最优的,如果我们选 \(S_0,x\) 之后还选了 \(y\),那么完全可以 \(S_0:=S_0+x,y:=x\)。
需要注意不能出现 \(S_0=S_2=\varnothing\),扫一遍即可,时间复杂度 \(O(n)\)。
\(type=3\)
考虑对 \(type=1\) 计数,首先容斥,总贡献为所有子序列的长度之和,设 \(n\) 的答案为 \(f_n\)。
那么显然有递推式:\(f_n = 2f_{n-1} + 2^{n-1}\),求出来即可。
然后首先可以扣掉颜色段数为 \(1\) 的子序列,接下来考虑扣掉颜色段数为 \(2\) 的子序列。
不妨枚举第一个颜色段的末尾下标 \(p\),对于 \(p\) 前面的限制是选若干个等于 \(p\) 的,对 \(p\) 后面的限制是选若干个一样的。
因此维护 \(pre_{0/1,i},suf_{0/1,i}\) 代表前后缀的贡献和和方案数,记得最后要减去一个总方案数。
扫一遍前后缀即可,时间复杂度 \(O(n)\)。
\(type=4\)
前面的三个部分应该都是平凡的,首先可以 \(O(2^nn)\) 暴力,然后场上根据暴力想了一个 \(O(n^4) \sim O(n^5)\) 的做法。
大概是枚举前面两个相同的,后面两个相同的下标算贡献,没写出来也不保证正确。
我们重新审视 \(type=2\) 的限制,发现这个限制并不方便计数,我们对其做转化:
记 \(k\) 为满足前 \(k\) 个两两不同,后 \(k\) 个两两不同的最大值。那么每个序列的贡献为 \(n-k-[k=n-1]\)。
\([k=n-1]\) 的意义就是首尾相同,且中间都不同的序列答案应该是 \(0\)。
对于这个式子,\(\sum n=f_n\) 已经在上面计算过,\([k=n-1]\) 可以枚举 \(p,q(p<q,a_p=a_q)\),设 \(x\) 在 \((p,q)\) 的出现次数为 \(b_x\)。
由于中间的数字两两不同,那么每个数 \(x\) 有 \(b_x\) 种选择,或者干脆不选。那么答案即为 \(\sum_{p<q} \prod_{c \ne a_p} (b_c+1)\),这个可以在 \(O(n^3)\) 时间内计算。
现在考虑如何计算最难算的 \(\sum k\)。考虑差分贡献,把贡献 \(k\) 拆分到 \(1 \sim k\) 每个上面。我们枚举 \(p,q\) 代表第 \(k'(k' \le k)\) 个前缀和后缀下标的位置。
因为贡献被拆分了,所以我们不关心 \(k'\) 的值,我们只需要知道每种 \(k'\) 的方案之和加起来即为答案。
观察到 \(p,q\) 并不存在偏序关系,不妨先考虑 \(p<q\) 怎么做,考虑限制:
选择若干个数,强制选定 \(p,q\),使得 \([1,p],[q,n]\) 中选择的数的个数相等,并且 \([1,p]\) 选择的数互不相同,\([q,n]\) 选择的数互不相同,对 \((p,q)\) 无限制。
中间的 \((p,q)\) 区间贡献系数显然为 \(2^{q-p-1}\),我们把 \([1,p]\) 选择的个数减去 \([q,n]\) 的个数看成下标进行背包。
不过由于 \([1,p]\) 可以全部放在 \([q,n]\) 前面,可以看作是若干体积为 \(1\) 的物品。物品的系数类似上面的 \([k=n-1]\)。
这样做一次背包是 \(O(n^2)\) 的,枚举 \(p,q\) 也是 \(O(n^2)\) 的,这样是 \(O(n^4)\) 的难以通过。
不过可以固定 \(p\),观察到 \(q\) 移动时物品更改个数是 \(O(1)\) 的,那么就可以回撤背包做到 \(O(n^3)\) 了。
继续观察 \(p>q\) 怎么做,考虑限制:
选择若干个数,强制选定 \(p,q\),使得 \([1,p],[q,n]\) 中选择的数的个数相等,并且 \([1,p]\) 选择的数互不相同,\([q,n]\) 选择的数互不相同。
跟上面不同的地方在于,如果在 \((q,p)\) 中区间选定一个 \(a_i=x\),那么 \([1,q),(p,n]\) 都不能再选定 \(x\)。反之也是。
也就是说,这个背包对于一种物品,有三种选择(\(+1,0,-1\) 体积,价值均不同),直接做仍然是 \(O(n^4)\) 的。
考虑这个背包怎么回撤?注意到背包等于乘上一个有交换律的稀疏矩阵,对这个稀疏矩阵高斯消元即可,消一次是 \(O(n)\) 的。
或者换一种表达方式,\(g_i = \sum af_{i-1}+bf_i +cf_{i+1}\),那么 \(g_{n+1}\) 只会由 \(af_{n}\) 转移过来,可以解出 \(f_n\),\(g_n\) 由 \(af_{n-1}+bf_{n}\) 转移而来,可以解出 \(f_{n-1}\),依次类推。
因为这是背包删除一组加入过的物品,这个方程组应该是一定有唯一解的,时间复杂度 \(O(n^3)\)。