qoj6344. The Best Problem of 2021

做了很久的好题,当然要纪念一下(

如果给出的线性基不是最小的,那么无解。

考虑简单转化一下问题。先把线性基消元,求出 \(X\) 在线性基中的 \(\text{Rank}\),再判一下全选是否无解。令 \(X\to \text{Rank}(X)\),问题可以转化为:在 \(\{0,1,..,X\}\) 的子集中选若干个数,使得子集线性基满秩(即秩等于 \(\{0,1,..,X\}\) 全选的秩)。(这里把 \(0\) 算进去了,最后答案要除以 \(2\)

考虑子空间容斥(子线性基容斥?)。枚举所有的不同的子线性基(也就是枚举所有进行高斯消元后的线性基),算出 \(0\sim X\) 内有 \(t\) 个数在该线性基内,则该线性基的子集答案为 \(2^t\)

对于秩为 \(i\) 的线性基,求出 \(ans_i = \sum\) 所有秩为 \(i\) 的线性基的答案。最后进行一下 q-二项式反演,可以得到所有秩恰好\(i\) 的线性基答案。

一份能过样例 1 的暴力容斥代码(只求了满秩的答案)


接下来考虑怎么数 \(ans_i\)。(接下来讨论的全部都是消元后的线性基

考虑求出 \(X\) 在该子线性基中的 \(\text{Rank}\),那个数是 \(2^{\text{Rank}(X)}\)

考虑如何表示 \(Rank(X)\)

\(now = 0\),从高到低一个一个看 \(X\) 的位。

如果 \(now\)\(X\) 在这位相同,则不用变化。

如果不同:

  • 如果线性基中有这位,则让 \(now\) XOR 上,使这位相同,然后继续
  • 如果没有,并且 \(now=0,X=1\)\(\text{Rank} = \text{当前高位选了的 Rank}+2^{\text{低位还有的基个数}}\)
  • 如果没有,并且 \(now=1,X=0\)\(\text{Rank} = \text{当前高位选了的 Rank}\)

大概就是求 \(now\)\(X\) 的 LCP 的过程,并且第一个不同的位有两类情况。

分析完毕,考虑写一个 dp。从高位到低位 dp 没法定下当前选了几个基,不太行,要从低位到高位 dp。

首先判掉子线性基没有选最高位的情况,这种情况下 \(Rank\) 就是 \(2^k\)

剩下是 子线性基选了最高位 的情况。

\(f(i,j)/g(i,j)\) 表示 没有/有 触碰到 \(now\)\(X\) 的 LCP,选了 \(j\) 个基的 ans 总和。

转移细致讨论清楚即可。

注意到由于钦定子线性基一定选了最高位,所以如果下面有一个位没有选基,则这位 \(now\)\(0/1\) 的概率各为 \(\frac{1}{2}\),这也是前文为什么一定要判掉这个条件的原因。

代码

时间复杂度 \(O(n^3/w+n^2)\).

posted @ 2023-05-04 22:54  Rainbow_qwq  阅读(148)  评论(0编辑  收藏  举报