小C的利是题解
小C的利是题解
简要题意
给定 \(n,K,A_{i,j}\) ,判断是否存在一个排列 \(p\) 满足:
-
\(\forall 1\le i\le n,A_{i,p_i}\not= -1\)
-
\(\sum_{i=1}^nA_{i,p_i}\equiv 0 \pmod{K}\)
\(1\le n,K\le100,-1\le A_{i,j}<K\)
题解
这个题非常神奇
首先咱们要找到一个 \(P\) 满足 \(P\bmod K=1\) ,并找到 \(P\) 的原根 \(g\) 。(为什么要找到这些东西以后讲)
由于 \(n\) 非常大,所以我们要找到一种快速的方法遍历所有排列,想到了什么?
行列式!
\(det(A)=\sum\limits sgn(p)\prod_{i=1}^n A_{i,p_i}\)
但是 \(\prod_{i=1}^n A_{i,p_i}\) 求的是积啊,这可咋办?
把它放到指数上面 \(\prod_{i=1}^n G^{A_{i,P_i}}=G^S\) ,\(S=\sum A_{i,P_i}\) 就可以了。
但是还有问题,怎么根据行列式判断是否存在一个满足要求的排列呢?
咱们可以找到一个合适的 \(G\) 和一种计算方法,满足对于一个排列 \(p\) 只有 \(S\bmod K=0\) 时才能求出它的贡献,否则求出的值都是 0。
这玩意不好找吧?这就是这一题的神奇之处,看下面这种构造方式。
令 \(G=g^{\frac{P-1}{k}}\) ,求出
单独拎出来一个排列 \(p\) ,它的贡献是 \(sgn(p)\sum\limits_{t=0}^{K-1} (G^{S})^t\) 。
这东西是一个公比为 \(G\) 的等比数列,对它求和得:\(sgn(p)\frac{G^{KS}-1}{G^S-1}\)
当 \(S\bmod K=0\) 时 ,和等于 \(K\) 。
否则,和等于 0,因为 \(G=g^\frac{P-1}{k}\) ,\(G^k=g^{P-1}\) ,所以分子为 0。所以 \(S\bmod K\not=0\) 的排列对这个行列式没有贡献。
所以我们只要检查这个行列式是否为 0 即可。
FAQ
Q:为什么我的答案不对?
A:如果你确保你其他地方都没有问题(找原根之类的),那么可能是这个式子中 \(sgn(p)\sum\limits_{t=0}^{K-1} (G^{S})^t\) 应该有贡献的排列的值要么是 \(K\) 要么是 \(-K\) ,可能构造的数据恰好让你加加减减得到 0 了。可以怎么做:把 \(\prod_{i=1}^n {G^t}^{A_{i,p_i}}\) 改成 \(\prod_{i=1}^n B_{i,p_i}{G^t}^{A_{i,p_i}}\),其中 \(B_{i,p_i}\) 是你随机乘上的一个权值,目的是使得对于 \(S\bmod P=0\) 的排列的贡献是 \(sgn(p)C\sum\limits_{t=0}^{K-1} (G^{S})^t\)(\(C\) 是一个常数),这样的话所有合法的排列的贡献之和几乎不会是0。
Q:为什么要找到 \(g\) 令 \(G^k=1\) ,一直到最后你都没用的那个 \(g\),直接找到一个 \(X^k=1\) 不就好了?
A:注意原根有这样一个性质 \(g^0,g^1,\dots,g^{P-1}\) 两两不同。我们只希望 \(G^0=1\) ,不让 \(G=g^\frac{P-1}{k}\) 的话可能 \(G^{其他幂次}\) 会等于1,这会使我们会把不合法的排列判断成合法的排列。
Q: \(A_{i,p_i}=-1\) 的话 \({G^t}^{A_{i,p_i}}\) 该怎么办,要特判一下,直接设为0。