专栏文章

拾起,单位根的记忆

个人记录参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@min4ihem
此快照首次捕获于
2025/12/01 20:26
3 个月前
此快照最后确认于
2025/12/01 20:26
3 个月前
查看原文

拾起,单位根的记忆

阶:

定义:

对于 aZa\in \mathbf{Z}mN+m \in \mathbf{N}_+ama\perp m,满足 an1(modm)a^n \equiv 1\pmod{m} 的最小正整数 nn 记为 δm(a)\delta_m(a)
约定:下列性质均在 aZa\in \mathbf{Z}mN+m \in \mathbf{N}_+ama\perp m 的情况下研究

性质一:

a0,a1,a2,,aδm(a)1a^0,a^1,a^2,\dots ,a^{{\delta_m(a)}-1}mm 互不相同

性质二:

an1(modm)a^n\equiv 1 \pmod{m} 当且仅当 δm(a)n\delta_m(a) \mid n

性质三:

δm(ak)=δm(a)gcd(δm(a),k)\delta_m(a^k)=\dfrac{\delta_m(a)}{\gcd(\delta_m(a),k)}

性质四:

lcm(δm(a),δm(b))gcd(δm(a),δm(b))δm(ab)lcm(δm(a),δm(b)) \dfrac{\operatorname{lcm}(\delta_m(a),\delta_m(b))}{\operatorname{gcd}(\delta_m(a),\delta_m(b))} \mid \delta_m(ab) \mid \operatorname{lcm}(\delta_m(a),\delta_m(b))
更为简单的形式:δm(ab)=δm(a)δm(b)    δm(a)δm(b) \delta_m(ab)=\delta_m(a)\delta_m(b) \iff \delta_m(a) \perp \delta_m(b)

性质五:

总存在 cc,满足 δm(c)=lcm(δm(a),δm(b))\delta_m(c)=\operatorname{lcm}(\delta_m(a),\delta_m(b))

原根:

定义:

若存在 gg 满足 δm(g)=φ(m)\delta_m(g)=\varphi(m),则称 gg 为模 mm 的原根

原根判定定理:

对于 m3m \ge 3gmg \perp mgg 是模 mm 的原根当且仅当对于所有 pφ(m)p \mid \varphi(m),都有 gφ(m)p≢1(modm)g^{\frac{\varphi(m)}{p}} \not\equiv1 \pmod m

原根个数定理:

mm 的原根个数为 φ(φ(m))\varphi({\varphi{(m)})}

原根存在定理:

mm 的原根存在当且仅当 m=1,2,4,pe,2pem=1,2,4,p^e,2p^e,其中 pp 为奇质数且 eN+e \in \mathbf{N}_+

求原根的算法:

从小到大逐一枚举并判断,直到找到原根

代码:

时间复杂度为 O(n14logn)O(n^{\frac{1}{4}}\log n),可以找到所有原根
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1000005;
typedef long long ll;
int T,cnt,phi[N],pri[N]; vector<int> factor,ans; bool vis[N];
void init(int n){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
		for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
			vis[i*pri[j]]=true;
			if(i%pri[j]==0){
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			else phi[i*pri[j]]=phi[i]*phi[pri[j]];
		}
	}
}
int qpow(ll a,ll b,int mod){
	ll res=1;
	while(b){
		if(b&1) res=res*a%mod;
		a=a*a%mod; b>>=1;
	} return res;
}
void divide(int x){
	for(int i=2;i*i<=x;i++){
		if(x%i==0){
			factor.push_back(i);
			while(x%i==0) x/=i;
		}
	}
	if(x>1) factor.push_back(x);
}
bool exist(int n){
	if(n==2||n==4) return 1;
	if(n%2==0) n/=2;
	for(int i=2;pri[i]<=n;i++){
		if(n%pri[i]==0){
			while(n%pri[i]==0) n/=pri[i];
			return n==1;
		}
	}
	return 0;
}
int main(){
	init(1000000); scanf("%d",&T);
	while(T--){
		int n,d; scanf("%d%d",&n,&d);
		if(!exist(n)){
			puts("0\n");
			continue;
		}
		factor.clear(); ans.clear(); divide(phi[n]);
		int g;
		for(int i=1;;i++){
			bool is=1;
			if(__gcd(i,n)!=1) continue;
			for(int j=0;j<factor.size();j++){
				if(qpow(i,phi[n]/factor[j],n)==1){ is=0; break; }
			}
			if(is){ g=i; break; }
		}
		ll power=1;
		for(int s=1;ans.size()<phi[phi[n]];s++){
			power=power*g%n;
			if(__gcd(phi[n],s)==1) ans.push_back(power);
		}
	}
}

单位根反演:

主要形式:[kn]=1ki=0k1ωkin[k\mid n]=\frac{1}{k}\sum\limits_{i=0}^{k-1} \omega_{k}^{in}
在模 mm 意义下,取 ωk=gφ(m)k\omega_k=g^{\frac{\varphi(m)}{k}},一般题目的 mm 为质数,所以 ωk=gm1k\omega_k=g^{\frac{m-1}{k}}

多项式中的问题:

对于多项式 f(x)f(x),求 i[xi]f(x)[ki]\sum_i[x^i]f(x)[k\mid i]
用单位根反演:Ans=i[xi]f(x)1kj=0k1ωkij=1kj=0k1i[xi](ωkj)if(x)=1kj=0k1f(ωkj)Ans=\sum_i[x^i]f(x)\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{ij}=\frac{1}{k}\sum_{j=0}^{k-1}\sum_i[x^i](\omega_k^{j})^if(x)=\frac{1}{k}\sum_{j=0}^{k-1}f(\omega_k^j)

例题:

约定:保证 kmod1k\mid mod-1modmod 为质数且存在模 modmod 的原根

题目:#6247. 九个太阳

i=0n(ni)[ki]\sum_{i=0}^n \binom{n}{i}[k\mid i]

解答:

  • Ans=1ki=0k1f(ωki)Ans=\frac{1}{k}\sum_{i=0}^{k-1}f(\omega_k^i),其中 [xi]f(x)=(ni)[x^i]f(x)=\binom{n}{i}
  • f(x)=1ki(ni)xi=(1+x)nf(x)=\frac{1}{k}\sum_i \binom{n}{i}x^i=(1+x)^n
  • Ans=1ki=0k1(1+ωki)nAns=\frac{1}{k}\sum_{i=0}^{k-1}(1+\omega_k^i)^n

题目:#6485. LJJ 学二项式定理

i=0n(ni)siai%4\sum_{i=0}^n \binom{n}{i} s^i a_{i\% 4}

解答:

  • 枚举 j=i%4j=i\% 4,求 i=0n(ni)siaj[4ij]\sum_{i=0}^n \binom{n}{i} s^i a_{j}[4\mid i-j]
  • Ans=aji=0n(ni)si×14t=03ω4titjAns=a_j\sum_{i=0}^n\binom{n}{i} s^i\times \frac{1}{4}\sum_{t=0}^{3} \omega_{4}^{ti-tj}
  • 再枚举 ttAns=aj4ω4tji=0n(ni)(s×ω4t)iAns=\dfrac{a_j}{4\,\omega_4^{tj}}\sum_{i=0}^n \binom{n}{i} (s\times\omega_4^t)^i
  • 后面的式子就是 (s×ω4t+1)n(s\times\omega_4^t+1)^n

题目:P10664 BZOJ3328 PYXFIB

i=1n[ki](ni)Fi\sum_{i=1}^n [k\mid i]\binom{n}{i}F_i,其中 FiF_i 表示斐波那契数列

解答:

  • 值得注意的是,矩阵乘法和单位根反演是兼容的
  • [Fi1Fi2][1110]=[FiFi1]\begin{bmatrix}F_{i-1}&F_{i-2}\end{bmatrix}\ast \begin{bmatrix}1&1\\1&0\end{bmatrix}=\begin{bmatrix}F_{i}&F_{i-1}\end{bmatrix}
  • FiF_i 是矩阵的第一项,我们可以求出最终的矩阵,则答案为此矩阵的第一项
  • Ans=i=1n[ki](ni)GAiAns=\sum_{i=1}^n[k\mid i]\binom{n}{i}G\ast A^i,其中 GG 为初始矩阵,AA 为转移矩阵
  • 反演可得 Ans=Gki=0k1(Aωki+E)n Ans=\frac{G}{k} \sum_{i=0}^{k-1} (A\omega_k^i+E)^n,其中 EE 为单位矩阵

题目:#5370. 循环序列

i=0(kni+x)\sum_{i=0}\binom{k}{ni+x}

解答:

  • Ans=1ni=0n1ωnix(1+ωni)kAns=\frac{1}{n}\sum_{i=0}^{n-1}\omega_n^{-ix}(1+\omega_n^i)^k

题目:P5591 小猪佩奇学数学

i=0n(ni)piik\sum_{i=0}^n \binom{n}{i}p^i\lfloor \frac{i}{k} \rfloor

解答:

  • Ans=i=0n(ni)piiimodkkAns=\sum_{i=0}^{n} \binom{n}{i}p^i \ast \frac{i-i\bmod k}{k}
  • Ans=1ki=0n(ni)pii1ki=0n(ni)pi(imodk)Ans=\frac{1}{k} \sum_{i=0}^{n} \binom{n}{i}p^i i -\frac{1}{k}\sum_{i=0}^{n} \binom{n}{i}p^i(i\bmod k)
  • 先不管 1k\dfrac{1}{k},将式子拆成左右两边处理
  • left=i=0n(ni)piileft=\sum_{i=0}^{n} \binom{n}{i}p^i i
  • left=ni=1n(n1i1)pileft=n\sum_{i=1}^{n} \binom{n-1}{i-1}p^i
  • left=npi=0n1(n1i)pileft=np\sum_{i=0}^{n-1}\binom{n-1}{i}p^i
  • left=np(p+1)n1left=np(p+1)^{n-1}
  • right=i=0n(ni)pi(imodk)right=\sum_{i=0}^{n} \binom{n}{i}p^i(i \bmod k)
  • right=i=0n(ni)pit=0k1[t=imodk]tright=\sum_{i=0}^{n} \binom{n}{i}p^i\sum_{t=0}^{k-1}[t=i\bmod k]t
  • [t=imodk]=[kit]=1kj=0k1ωkj(it) [t=i \bmod k]=[k|i-t]=\frac{1}{k}\sum_{j=0}^{k-1} \omega_{k}^{j(i-t)}
  • right=1ki=0n(ni)pit=0k1tj=0k1ωkjiωkjtright=\frac{1}{k}\sum_{i=0}^{n} \binom{n}{i}p^i\sum_{t=0}^{k-1}t\sum_{j=0}^{k-1} \omega_{k}^{ji}\omega_{k}^{-jt}
  • 不管 1k\frac{1}{k}righti=0n(ni)piωkjit=0k1tj=0k1ωkjtright \rightarrow \sum_{i=0}^{n} \binom{n}{i}p^i \omega_{k}^{ji}\sum_{t=0}^{k-1}t\sum_{j=0}^{k-1}\omega_{k}^{-jt}
  • right=(ωkjp+1)nt=0k1tj=0k1ωkjtright=(\omega_{k}^{j}p+1)^n\sum_{t=0}^{k-1}t\sum_{j=0}^{k-1}\omega_{k}^{-jt}
  • 枚举 j,不管定值 (ωkjp+1)n(\omega_{k}^{j}p+1)^nrightt=0k1tωkjt right \rightarrow \sum_{t=0}^{k-1}t\omega_{k}^{-jt}
  • 我们知道,i=1nwi=wn+1ww1\sum_{i=1}^{n}w^i=\dfrac{w^{n+1}-w}{w-1}
  • F(n,w)=i=0niwi=i=1niwiF(n,w)=\sum_{i=0}^{n}iw^i=\sum_{i=1}^{n}iw^i
  • wF(n,w)=i=0niwi+1=i=1n+1(i1)wiwF(n,w)=\sum_{i=0}^{n}iw^{i+1}=\sum_{i=1}^{n+1}(i-1)w^{i}
  • (w1)F(n,w)=nwn+1i=1nwi=nwn+1wn+1ww1(w-1)F(n,w)=nw^{n+1}-\sum_{i=1}^{n}w^i=nw^{n+1}-\dfrac{w^{n+1}-w}{w-1}
  • right=1ωkj1((k1)ωkjk(ωkjkωkj)ωkj1)right=\dfrac{1}{\omega_{k}^{-j}-1}\begin{pmatrix}(k-1)\omega_{k}^{-jk} -\dfrac{(\omega_{k}^{-jk}-\omega_{k}^{-j})}{\omega_{k}^{-j}-1}\end{pmatrix}
  • right=1ωkj1((k1)1ωkjωkj1)=kωkj1right=\dfrac{1}{\omega_{k}^{-j}-1}\begin{pmatrix}(k-1) -\dfrac{1-\omega_{k}^{-j}}{\omega_{k}^{-j}-1}\end{pmatrix}=\dfrac{k}{\omega_{k}^{-j}-1}
  • 综上,Ans=1k(np(p+1)n1j=0k1(ωkjp+1)nωkj1)Ans=\dfrac{1}{k} \begin{pmatrix}np(p+1)^{n-1}-\sum_{j=0}^{k-1}\dfrac{(\omega_{k}^{j}p+1)^n}{\omega_{k}^{-j}-1}\end{pmatrix},注意讨论 ωkj=1\omega_{k}^{-j}=1 的情况

题目:P10084 [GDKOI2024 提高组] 计算

可转化为:1,2,,n1,2,\dots,n 的集合,求有多少个子集,满足子集元素和为 kk 的倍数,保证 knk\mid n
注意:此题不满足约定

解答:

  • 构造生成函数 f(x)=i=1n(1+xi)f(x)=\prod_{i=1}^n(1+x^i),则 [xk]f(x)[x^k]f(x) 就是子集和为 kk 的子集个数
  • 不难得到,Ans=i[xi]f(x)[ki]Ans=\sum_{i} [x^i]f(x)[k\mid i]
  • Ans=1ki=0k1f(ωki)Ans=\frac{1}{k}\sum_{i=0}^{k-1} f(\omega_k^i)
  • 考虑求 f(ωki)f(\omega_k^i),设 d=gcd(i,k)d=\gcd(i,k),则 f(ωki)=f(ωkdid)f(\omega_k^i)=f\left(\omega_{\frac{k}{d}}^{\frac{i}{d}}\right)
  • f(ωkdid)=(i=0kd1(1+ωkdi))ndk f\left(\omega_{\frac{k}{d}}^{\frac{i}{d}}\right)=\left(\prod\limits_{i=0}^{\frac{k}{d}-1} \left(1+\omega_{\frac{k}{d}}^i\right) \right)^\frac{nd}{k}
  • 我们知道 xn1=i=0n1(xωni)x^n-1=\prod_{i=0}^{n-1} (x-\omega_n^i),代入 x=1x=-1,得 (1)n1=i=0n1(1ωni)i=0n1(1+ωni)=1(1)n(-1)^n-1=\prod_{i=0}^{n-1} (-1-\omega_n^i)\Rightarrow\prod_{i=0}^{n-1} (1+\omega_n^i)=1-(-1)^n
  • f(ωkdid)=(1(1)kd)ndkf\left(\omega_{\frac{k}{d}}^{\frac{i}{d}}\right)=\left(1-(-1)^{\frac{k}{d}} \right)^\frac{nd}{k},可见当 2kd2\nmid\frac{k}{d} 时有贡献
  • Ans=1kdk2ndki[(i,k)=d][2kd]Ans=\frac{1}{k}\sum_{d\mid k} 2^{\frac{nd}{k}}\sum_{i}[(i,k)=d][2\nmid \frac{k}{d}]
  • Ans=1kdk2ndkφ(kd)[2kd]Ans=\frac{1}{k}\sum_{d\mid k} 2^{\frac{nd}{k}}\varphi(\frac{k}{d})[2\nmid \frac{k}{d}]
  • k=u×2mk=u\times 2^m,其中 2u2\nmid u,则 d=v×2md=v\times 2^m 才满足 [2kd][2\nmid \frac{k}{d}]
  • 最终可得 Ans=1kdu2nduφ(ud)Ans=\frac{1}{k}\sum_{d\mid u} 2^{\frac{nd}{u}}\varphi(\frac{u}{d})

题目:P6800 【模板】Chirp Z-Transform

给定多项式 f(x)f(x),求 f(c0),f(c1),,f(cm)f(c^0),f(c^1),\dots , f(c^m)

解答:

虽然与单位根反演无关
  • F(ci)=jajcijF(c^i)=\sum_{j} a^j c^{ij}
  • 人类智慧:ij=(i+j2)(i2)(j2)ij=\binom{i+j}{2}-\binom{i}{2}-\binom{j}{2}
  • F(ci)=c(i2)jajc(j2)×c(i+j2)F(c^i)=c^{-\binom{i}{2}}\sum_{j} a^jc^{-\binom{j}{2}}\times c^{\binom{i+j}{2}}
  • Ami=aic(i2)A_{m-i}= a^ic^{-\binom{i}{2}}Bi=c(i2)B_{i}=c^{\binom{i}{2}}
  • F(ci)=c(i2)jAmj×Bi+jF(c^i)=c^{-\binom{i}{2}}\sum_{j} A_{m-j}\times B_{i+j},发现是卷积,可做

题目:P5293 [HNOI2019] 白兔之舞

矩阵的转移是平凡的,可将问题变为对于每个 tt,求 i=0L(Li)[it(modk)]Wi\sum_{i=0}^L \binom{L}{i}[i\equiv t \pmod{k}]W^i

解答:

  • 先定 tti=0L(Li)[it(modk)]Wi=1ki=0k1ωkit(Wωki+E)L \sum_{i=0}^L \binom{L}{i}[i\equiv t \pmod{k}]W^i=\frac{1}{k}\sum_{i=0}^{k-1} \omega_{k}^{-it} (W\omega_k^i+E)^L
  • 构造多形式 f(x)f(x),满足 [xi]f(x)=1k(Wωki+E)L[x^i]f(x)=\frac{1}{k}(W\omega_k^i+E)^L
  • Anst=i=0k1ωkit[xi]f(x)=f(ωkt)=f((1ωk)t)Ans_t=\sum_{i=0}^{k-1} \omega_{k}^{-it}[x^i]f(x)=f(\omega_{k}^{-t})=f\left((\frac{1}{\omega_k})^t\right)
  • c=1ωkc=\frac{1}{\omega_k},即求所有的 f(ci)f(c^i),用上一题的做法即可

题目:TopCoder 11351 TheCowDivOne

{0,1,,n1}\{0,1,\dots,n-1\} 中选 kk 个数,和为 nn 的倍数的方案数,模 1e9+71e9+7k1e3k\le1e3n1e9n\le 1e9
注意:此题不满足约定

解答:

让我们请出二元生成函数
  • Ans=i[ni][xi][yk]j=0n1(1+xjy)Ans=\sum_{i}[n\mid i][x^i][y^k]\prod_{j=0}^{n-1}(1+x^jy)
  • Ans=i1nt=0n1ωnti[xi][yk]j=0n1(1+xjy)Ans=\sum_{i}\frac{1}{n}\sum_{t=0}^{n-1}\omega_n^{ti}[x^i][y^k]\prod_{j=0}^{n-1}(1+x^jy)
  • Ans=1nt=0n1[yk]j=0n1(1+ωntjy)Ans=\frac{1}{n}\sum_{t=0}^{n-1}[y^k]\prod_{j=0}^{n-1}(1+\omega_n^{tj}y)
  • d=gcd(t,n)d=\gcd(t,n)Ans=1nt=0n1[yk](i=0nd1(1+ωndiy))dAns=\frac{1}{n}\sum_{t=0}^{n-1}[y^k]\left(\prod_{i=0}^{\frac{n}{d}-1}\left(1+\omega_{\frac{n}{d}}^iy\right)\right)^d
  • 我们知道 xn1=i=0n1(xωni)x^n-1=\prod_{i=0}^{n-1} (x-\omega_n^i),代入 x=1yx=-\frac{1}{y},得 (1y)n1=i=0n1(1yωni)i=0n1(1+ωniy)=1(y)n(-\frac{1}{y})^n-1=\prod_{i=0}^{n-1} (-\frac{1}{y}-\omega_n^i)\Rightarrow\prod_{i=0}^{n-1} (1+\omega_n^iy)=1-(-y)^n
  • Ans=1ndnφ(nd)[yk](1(y)nd)dAns=\frac{1}{n}\sum_{d\mid n}\varphi(\frac{n}{d})[y^k]\left(1-(-y)^{\frac{n}{d}}\right)^d
  • Ans=1ndnφ(d)[yk](1(y)d)ndAns=\frac{1}{n}\sum_{d\mid n}\varphi(d)[y^k]\left(1-(-y)^{d}\right)^\frac{n}{d},可以看出,当 dkd\mid k 时才有贡献
  • Ans=1ndn,kφ(d)[ykd](1+(1)d+1y)ndAns=\frac{1}{n}\sum_{d\mid n,k}\varphi(d)[y^{\frac{k}{d}}]\left(1+(-1)^{d+1}y\right)^\frac{n}{d}
  • Ans=1ndn,kφ(d)(ndkd)(1)(d+1)kdAns=\frac{1}{n}\sum_{d\mid n,k}\varphi(d)\dbinom{\frac{n}{d}}{\frac{k}{d}}(-1)^{(d+1)\frac{k}{d}},发现 kk 较小,可做

题目:HT-054-NOI 优秀的匹配

给定二维数组,问是否有排列 pp,使 ki=1nai,pik\mid \sum_{i=1}^n a_{i,p_i}i,ai,pi1\forall \, i,a_{i,p_i}\ne -1
数据范围:1n,k1001\le n,k \le 100

解答:

  • 不易想到,行列式的完全展开式里自带枚举排列
  • 构造矩阵 AA,当 ai,j=1a_{i,j}=-1 时,Ai,j=0A_{i,j}=0,否则 Ai,j=xai,jA_{i,j}=x^{a_{i,j}}
  • ki,[xi]det(A)0\exist \,k\mid i,[x^i]det(A)\ne 0,则有解
  • 若都等于 0,也可能是正负抵消了,因此将 Ai,j=rand()×xai,jA_{i,j}=rand()\times x^{a_{i,j}},这样可以避免正负抵消
  • 因为加了随机化,事实上,求 Ans=ki[xi]det(A)Ans=\sum_{k\mid i} [x^i]det(A) 是否为 0 即可
  • 单位根反演,Ans=1ki=0k1f(ωki)Ans=\frac{1}{k}\sum_{i=0}^{k-1} f(\omega_k^i),其中 f(x)f(x) 就是 det(A)det(A) 对应的多项式
  • 将每个 ωki\omega_k^i 代入算行列式即可

总结:何时用单位根反演:

出现以下情况时,可以考虑:
  • kmod1k\mid mod-1modmod 为质数,有模 modmod 的原根
  • [ki][k\mid i]
  • ix(modk)[kix]i \equiv x \pmod{k} \Rightarrow [k\mid i-x]
  • ik\lfloor \frac{i}{k} \rfloor,枚举 j=imodkj=i\bmod k,变为 ijk\frac{i-j}{k}
  • if(ki+x)\sum_i f(ki+x),可化为 jf(j)[jx(modk)]\sum_j f(j) [j\equiv x \pmod{k} ]
  • 求和为 kk 的倍数的方案数

评论

1 条评论,欢迎与作者交流。

正在加载评论...