小C的利是题解
简要题意
给定 (n,K,A_{i,j}) ,判断是否存在一个排列 (p) 满足:
-
(forall 1le ile n,A_{i,p_i} ot= -1)
-
(sum_{i=1}^nA_{i,p_i}equiv 0 pmod{K})
(1le n,Kle100,-1le A_{i,j}<K)
题解
这个题非常神奇
首先咱们要找到一个 (P) 满足 (Pmod K=1) ,并找到 (P) 的原根 (g) 。(为什么要找到这些东西以后讲)
由于 (n) 非常大,所以我们要找到一种快速的方法遍历所有排列,想到了什么?
行列式!
(det(A)=sumlimits 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) 只有 (Smod K=0) 时才能求出它的贡献,否则求出的值都是 0。
这玩意不好找吧?这就是这一题的神奇之处,看下面这种构造方式。
令 (G=g^{frac{P-1}{k}}) ,求出
单独拎出来一个排列 (p) ,它的贡献是 (sgn(p)sumlimits_{t=0}^{K-1} (G^{S})^t) 。
这东西是一个公比为 (G) 的等比数列,对它求和得:(sgn(p)frac{G^{KS}-1}{G^S-1})
当 (Smod K=0) 时 ,和等于 (K) 。
否则,和等于 0,因为 (G=g^frac{P-1}{k}) ,(G^k=g^{P-1}) ,所以分子为 0。所以 (Smod K ot=0) 的排列对这个行列式没有贡献。
所以我们只要检查这个行列式是否为 0 即可。
FAQ
Q:为什么我的答案不对?
A:如果你确保你其他地方都没有问题(找原根之类的),那么可能是这个式子中 (sgn(p)sumlimits_{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}) 是你随机乘上的一个权值,目的是使得对于 (Smod P=0) 的排列的贡献是 (sgn(p)Csumlimits_{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。