CF1327F题解

神奇 \(dp\)优化。

位运算每位独立,因此可以算二进制每一位的方案数,最后乘起来。

由于这样有 \(\log n\) 次计算,则每次计算复杂度必须为线性。

现在每个限制就等价于一些区间全为1,一些区间不全为1,怎么那么像冒泡排序A性质

现在不考虑第一种限制,满足第二种限制需要每个区间里都至少有一个 \(0\),跟 \(0\) 的位置有关。

考虑暴力\(dp\),设 \(dp[i][j]\) 表示考虑前 \(i\) 个位置,最后一个 \(0\) 的位置是 \(j\),且满足右端点小于等于 \(i\) 的所有限制的方案,设 \(l[i]\) 表示这些限制中右端点的最大值。

  • 对于 \(j\in[0,l_i-1]\)\(dp[i][j]=0\),因为不能满足 \(l[i]\) 的限制。

  • 对于 \(j\in[l_i,i-1]\)\(dp[i][j]=dp[i-1][j]\),因为 \(i\) 位置只能是 \(1\)

  • 对于 \(j=i\),相当于只需要前 \(i-1\) 位满足 \(i-1\) 前面的限制。

    \[dp[i][j]=\sum_{k=l_{i-1}}^{i-1}dp[i-1][k] \]

对于第一种情况不用考虑,只用在最后统计答案时忽略掉前面。

然后发现 \(dp_i\) 相较于 \(dp_{i-1}\) 大部分都相同,只有 \(dp[i][i]\) 不同,因此只需要求 \(dp[i][i]\)

\(s[i][j]=\sum_{k=1}^{j}dp[i][k]\),则 \(dp[i][i]=s[i-1][i-1]-s[i-1][l_{i-1}-1]\),可以 \(\mathcal{O}(1)\) 求。

\(l_i\) 一定单增,所以以上步骤只用从前往后扫一遍,维护 \(l_i\) 和长度为 \(n\)\(s\) 数组,表示 \(dp_i\) 的前缀和,\(i\) 相较于 \(i-1\) 只有 \(s_i\) 会加上 \(dp[i][i]\),最后答案就是 \(s[n]-s[l[n]-1]\)

考虑限制 \(1\),发现只用在上述步骤中跳过必须填 \(1\) 的位就行了。

至于判断某一位是否必须填 \(1\),相当于区间覆盖 \(1\),可以差分。

posted on 2022-11-06 16:59  cool_tyl  阅读(9)  评论(0)    收藏  举报