单位根反演
单位根反演
单位根
定义
\(n\) 次单位根(简称为单位根)定义为 \(x^n=1\) 在复数域上的根,总共有 \(n\) 个。
第 \(i\) 个根为 \(w_n^k=\cos\frac{2k\pi}{n}+i\sin\frac{2k\pi}{n}\),或者根据欧拉公式可以记作 \(w_n^k=e^{i\frac{2k\pi}{n}}\)。
性质
-
单位根中有一个是 \(1\),相邻单位根的比值相等,所以其实可以记这 \(n\) 个单位根为 \(w^0=1,w^1,\cdots,w^{n-1}\)。
-
单位根的几何意义是把单位圆圆周 \(n\) 等分,其中一个点是 \((1,0)\),\(w^k\) 相当于在单位元上转了 \(\frac k n\) 圈。
-
单位根有周期性,\(\forall k\in \mathbb{N},w^i=w^{i+kn}\)。
-
单位根的模长 \(|w|=1\)。
单位根与原根
常见模数 \(mod=998244353\) 的原根是 \(g=3\),模意义下的单位根有结论 \(w=g^{\frac{mod-1}{n}}\),要求 \(n\mid (mod-1)\)。
单位根反演
核心
证明:
当 \(n\nmid k\) 时:根据等比数列求和,\(\sum_{i=0}^{n-1} w^{ik}=\frac{w^{kn}-1}{w^k-1}\),根据单位根的周期性 \(w^{kn}=w^0=1\),但是 \(w^k\not =1\),所以分子为 \(0\) 分母不为 \(0\),比值为 \(0\)。
当 \(n\mid k\) 时:根据单位根的周期性 \(w^{ik}=w^0=1\),所以 \(\frac 1 n\sum_{i=0}^{n-1}1=1\)。
推论
设有 \(m\) 次多项式 \(F(x)\),设 \(f_k=[x^k]F(x)\)。
证明:直接暴力带入
\[\begin{align}\sum_{k=0}^m[n\mid k]f_k&=\sum_{k=0}^mf_k\times \frac 1 n\sum_{i=0}^{n-1}w^{ik}\\&=\frac 1 n \sum_{k=0}^m\sum_{i=0}^{n-1}f_iw^{ik}\\&=\frac 1 n \sum_{i=0}^{n-1}\sum_{k=0}^mf_i(w^i)^k\\&=\frac 1 n \sum_{i=0}^{n-1}F(w^i)\end{align} \]
这表明在求解某些多项式的下标为 \(k\) 的倍数函数值之和时,若 \(F\) 好求而求解 \(f\) 是困难的,可以借助上述方法。例如求解 \((a+b)^n\) 的系数是困难的,而求解整体的值只需要快速幂。
另一方面如果求数组下标为 \(k\) 的倍数之和,可以尝试构造生成函数,然后利用单位根反演求解。
HT-054-NOI 优秀的匹配
题面:
给定一张左右各 \(n\) 个点无重边无自环的二分图及一个正整数 \(k\),每条边有一个非负整数的边权,我们想知道这张图是否存在一个“优美”匹配。一个匹配是“优美”匹配当且仅当它是一个完美匹配且所有匹配边权值之和为 \(K\) 的倍数。连边情况以矩阵 \(a_{i,j}\) 给出,若 \(a_{i,j}=-1\) 表示没有边,否则表示左部 \(i\) 到右部 \(j\) 有权 \(a_{i,j}\) 的边。\(1\leq n,k\leq 100\)
题解:
题目即求是否存在一个排列 \(p\) 使得 \(\forall i\in[1,n],a_{i,p_i}\not=-1\) 且 \(k\mid\sum_{i=1}^n a_{i,p_i}\)。需要对所有排列考虑这个问题,又看到 \(n\leq 100\),你发现 \(n^3\) 的行列式天然自带枚举所有排列。
考虑行列式的展开式 \(det(A)=\sum_{p}(-1)^{sign(p)}\prod_{i=1}^n A_{i,p_i}\)。但是对于每个 \(p\) 行列式求的值是乘积,但是现在我们要求边权和,套路的利用多项式令 \(A_{i,j}=x^{a_{i,j}}\)(如果 \(a_{i,j}=-1\),则令 \(A_{i,j}=0\)),这样就是求和了。问题转变成了检查多项式 \(det(A)\) 的每个 \(k\) 的倍数次方前的系数是否有值。
但是这个转化不咋对,因为 \((-1)^{sign(p)}\) 有可能导致正负抵消掉,而每个 \(p\) 会给对应的系数贡献 \(\pm1\),构造数据卡掉是容易的。那让每个 \(p\) 的贡献不是 \(\pm1\) 而是随机数不就行了吗?令 \(A_{i,j}=rnd()x^{a_{i,j}}\),那这样每个 \(p\) 的贡献就是随机的了,如果有 \(k\) 的方案那么 \(x^k\) 前的系数就极大概率不为 \(0\),而且这个错误跟数据没什么关系,不放心那就进行多次随机测试即可。
记 \(f_i=[x^i]det(A)\)。所以现在只需要求 \(\forall k\mid i,f_i\) 是否有值,因为系数随机,所以求 \(\sum_i [k\mid i]f_i\) 是否有值其实也没问题,这就是单位根反演的板子了。求出 \(k\) 的单位根,分别令 \(x=w_k^i\) 带入求行列式再加和,就知道了 \(\sum_i[k|i]f_i\) 的值了。复杂度 \(O(n^4)\)。
代码被核桃封禁了,看不了。