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\) 的线性基答案。
接下来考虑怎么数 \(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)\).