在一些计数的问题中,常常要求对结果取模,但是在计算非常庞大的次幂的时候,无法直接取模,可以先把底数对 p 取模,指数对$ \varphi(p)$ 取模,再计算次幂,有效地降低时间复杂度。
第二章 同余
0x20 同余
0x21 整数的取余运算
0x21.1 整数的取余运算(模运算)
定义:带余除法,设 a , b 是整数,且 b > 0,使得 a=bq+r,且 0≤r<b ,称 q 为商, r 为余数。
显然带余除法中的商和余数都是唯一的,在下文中将商记为 a / b ,将余数记为 a % b ,/ 与 % 的运算优先级与乘除法相同。
取模运算:a % p (或a mod p),表示 a 除以 p 的余数。
模 p 加法:(a+b)%p ,其结果是a + b 算术和除以p的余数,也就是说,( a + b ) = k p + r ,则( a + b ) % p = r 。
模 p 减法:( a − b ) % p,其结果是a − b算术差除以p的余数。
模 p 乘法:( a ∗ b ) % p,其结果是a ∗ b 算术乘法除以p的余数。
a % b = a − b × ⌊ a b ⌋ a \% b = a-b\times \lfloor\frac{a}{b}\rfloor a % b = a − b × ⌊ b a ⌋ ,即若 a % b = c ,则 a = b x + c ,x = ⌊ a b ⌋ x= \lfloor\frac{a}{b}\rfloor x = ⌊ b a ⌋ 。
n % p 得到结果的正负由被除数 n 决定,与 p 无关。
结合率:
( ( a + b ) % p + c ) % p = ( a + ( b + c ) % p ) % p ((a+b) \% p + c) \% p = (a + (b+c) \% p) \% p ( ( a + b ) % p + c ) % p = ( a + ( b + c ) % p ) % p
( ( a × b ) % p × c ) % p = ( a × ( b × c ) % p ) % p ((a\times b) \% p\times c)\% p = (a\times (b\times c) \% p) \% p ( ( a × b ) % p × c ) % p = ( a × ( b × c ) % p ) % p
交换率:
( a + b ) % p = ( b + a ) % p (a + b) \% p = (b+a) \% p ( a + b ) % p = ( b + a ) % p
( a × b ) % p = ( b × a ) % p (a\times b) \% p = (b\times a) \% p ( a × b ) % p = ( b × a ) % p
分配率:
( ( a + b ) % p × c ) % p = ( ( a × c ) % p + ( b × c ) % p ) % p ((a +b)\% p\times c) \% p = ((a \times c) \% p + (b\times c) \% p) \% p ( ( a + b ) % p × c ) % p = ( ( a × c ) % p + ( b × c ) % p ) % p
若a % p = x , a % q = x , gcd ( p , q ) = 1 a\%p=x,a\%q=x,\gcd(p,q)=1 a % p = x , a % q = x , g cd( p , q ) = 1 ,则a % ( p × q ) = x a\%(p×q)=x a % ( p × q ) = x
更多关于模运算性质以及同余详见本文 0x22同余。
0x21.2 整数模意义下的加减乘乘方运算
( a + b ) % c = ( a % c + b % c ) % c (a+b) \%c=(a\%c+b\%c)\%c ( a + b ) % c = ( a % c + b % c ) % c
( a − b ) % c = ( a % c − b % c + c ) % c (a-b)\%c=(a\%c-b\%c+c)\%c ( a − b ) % c = ( a % c − b % c + c ) % c
( a × b ) % c = ( a % c ) × ( b % c ) % c (a \times b)\%c=(a\%c)\times (b\%c)\%c ( a × b ) % c = ( a % c ) × ( b % c ) % c
( a b ) % p = ( ( a % p ) b ) % p (a^b) \% p = ((a \% p)^b) \% p ( a b ) % p = ( ( a % p ) b ) % p
计算减法的时候,通常需要加上模数 c,防止出现负数。
O ( n l o g n ) O(nlogn) O ( n l o g n ) 的 大数快速幂算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <bits/stdc++.h> #define int long long using namespace std ; int mod;char s[20000001 ];int qqpow (int a, int b) { int ret=1 ; while (b) { if (b&1 )ret=(ret*a)%mod; a=(a*a)%mod; b>>=1 ; } return ret; } int qpow (int a, char *b, int len) { int ret=1 ; while (len>0 ) { if (b[len-1 ]!='0' ) ret=(ret*qqpow(a,b[len-1 ]-'0' ))%mod; a=(qqpow(a,10 ))%mod; len--; } return ret; } int read (char s[]) { int len=0 ; char ch; while ((ch=getchar())!='\n' ) { s[len++]=ch; } return len; } signed main () { int a; scanf ("%lld %lld" ,&a,&mod); getchar(); int len; len=read(s); cout <<qpow(a,s,len); return 0 ; }
对应题目改编自洛谷
【模板】扩展欧拉定理
题目背景
出题人也想写有趣的题面,可惜并没有能力。
题目描述
给你三个正整数,a , m , b a,m,b a , m , b ,你需要求:a b m o d m a^b \bmod m a b m o d m
输入格式
一行三个整数,a , m , b a,m,b a , m , b
输出格式
一个整数表示答案
样例 #1
样例输入 #1
样例输出 #1
样例 #2
样例输入 #2
1 998244353 12345 98765472103312450233333333333
样例输出 #2
提示
注意输入格式,a , m , b a,m,b a , m , b 依次代表的是底数、模数和次数
【样例 1 1 1 解释】
2 4 m o d 7 = 2 2^4 \bmod 7 = 2 2 4 m o d 7 = 2
【数据范围】
对于 100 % 100\% 1 0 0 % 的数据,1 ≤ a ≤ 1 0 9 1\le a \le 10^9 1 ≤ a ≤ 1 0 9 ,1 ≤ b ≤ 20000000 , 1 ≤ m ≤ 1 0 8 1\le b \le 20000000,1\le m \le 10^8 1 ≤ b ≤ 2 0 0 0 0 0 0 0 , 1 ≤ m ≤ 1 0 8 。
改了什么捏,当然是把b的数据范围改了。嘻嘻
那就可以过了
然而原题的数据范围是1 ≤ b ≤ 1 0 20000000 1≤b≤10^{20000000} 1 ≤ b ≤ 1 0 2 0 0 0 0 0 0 0
0x22 同余
若正整数 a 和 b 除以 m 的余数相等,则称 a ,b 模 m 同余,记作a ≡ b ( mod m ) a\equiv b\ (\text{mod}\ m) a ≡ b ( mod m ) 。
即 a % m = b % m
0x21.1 同余的性质
同余的基本性质:
性质21.1.1 : (自反性):a ≡ a ( m o d m ) a≡a(mod m) a ≡ a ( m o d m )
性质21.1.2 : (对称性):若 a ≡ b ( m o d m ) ,则 b ≡ a ( m o d m ) 若 a≡b(\mod\ m),则 b≡a(\mod\ m) 若 a ≡ b ( m o d m ) , 则 b ≡ a ( m o d m )
性质21.1.3 : (传递性):若 a ≡ b ( m o d m ) , b ≡ c ( m o d m ) ,则 a ≡ c ( m o d m ) 若 a≡b(\mod\ m),b≡c(\mod\ m),则 a≡c(mod m) 若 a ≡ b ( m o d m ) , b ≡ c ( m o d m ) , 则 a ≡ c ( m o d m )
性质21.1.4 : (同加性):若 a ≡ b ( m o d m ) ,则 a ± c ≡ b ± c ( m o d m ) 若 a≡b(mod m),则 a±c≡b±c(mod m) 若 a ≡ b ( m o d m ) , 则 a ± c ≡ b ± c ( m o d m )
性质21.1.5 : (同乘性):
若 a ≡ b ( m o d m ) ,则 a × c ≡ b × c ( m o d m ) 若 a≡b(\mod \ m),则 a×c≡b×c(\mod\ m) 若 a ≡ b ( m o d m ) , 则 a × c ≡ b × c ( m o d m ) ,若 a ≡ b ( m o d m ) , c ≡ d ( m o d m ) ,则 a × c ≡ b × d ( m o d m ) 若 a≡b(\mod\ m),c≡d(\mod\ m),则 a×c≡b×d(\mod\ m) 若 a ≡ b ( m o d m ) , c ≡ d ( m o d m ) , 则 a × c ≡ b × d ( m o d m )
性质21.1.6 : (同幂性):a c ≡ b c ( m o d m ) a^c≡b^c(\mod\ m) a c ≡ b c ( m o d m )
性质21.1.7 : (不满足同除性):若 a ≡ b ( m o d m ) a≡b(mod m) a ≡ b ( m o d m ) 不满足a ÷ c ≡ b ÷ c ( m o d m ) a÷c≡b÷c(mod m) a ÷ c ≡ b ÷ c ( m o d m )
性质21.1.8 : (满足同除性):
若a ≡ b ( m o d m ) a≡b(mod m) a ≡ b ( m o d m ) ,c ∣ a , c ∣ b c ∣ a , c ∣ b c ∣ a , c ∣ b , 则 $\cfrac{a}{c}≡\cfrac{b}{c}\ \pmod {\cfrac{m}{\gcd(m,c)} } $
或者可以换一种表述方式: 若 c a ≡ c b ( m o d m ) ca≡cb (\mod m) c a ≡ c b ( m o d m ) 则 a ≡ b ( m o d m gcd ( m , c ) ) a≡b \pmod {\frac{m}{\gcd(m,c)} } a ≡ b ( m o d g c d ( m , c ) m )
例如:gcd ( c , m ) = 1 ⟹ a ≡ b ( m o d m ) \gcd(c,m)=1\Longrightarrow a\equiv b\pmod m g cd( c , m ) = 1 ⟹ a ≡ b ( m o d m )
该性质会在取遍剩余系会用到。
推论21.1.9 :若$ a≡b(modm) , m’\ |\ m,则 , 则 , 则 a≡b \pmod {m’}$
推论21.1.10 :
a ≡ b ( m o d m i ) ( i = 1.. k ) a≡b \pmod {m_i} (i=1..k) a ≡ b ( m o d m i ) ( i = 1 . . k ) 等价于 a ≡ b ( m o d M ) = l c m ( m 1 , m 2 , . . m k ) a≡b \pmod M =\mathrm{lcm}(m1,m2,..mk) a ≡ b ( m o d M ) = l c m ( m 1 , m 2 , . . m k )
推论21.1.12 :a ≡ b ( m o d m ) a≡b(modm) a ≡ b ( m o d m ) 且 c ≡ d ( m o d m ) c≡d(modm) c ≡ d ( m o d m ) ⟹ a + c ≡ b + d ( m o d m ) \Longrightarrow a+c\equiv b+d\pmod m ⟹ a + c ≡ b + d ( m o d m )
推论21.1.13 :$a≡b(modm) $且 c ≡ d ( m o d m ) ⟹ a − c ≡ b − d ( m o d m ) c≡d(modm) \Longrightarrow a-c\equiv b-d\pmod m c ≡ d ( m o d m ) ⟹ a − c ≡ b − d ( m o d m )
0x21.2 费马小定理
若 p 是质数,则对于任意的整数 a 都有a p ≡ a ( m o d p ) a^p≡a \pmod p a p ≡ a ( m o d p ) 。若 $gcd(a,p)=1 $,即 a 不是 p 的倍数,则有 a p − 1 ≡ 1 ( m o d p ) a^{p−1}≡1\pmod p a p − 1 ≡ 1 ( m o d p )
费马小定理降幂:a k ≡ a k m o d ( p − 1 ) ( m o d p ) a^k\equiv a^{k\mod(p-1)}\;(\mod \;p) a k ≡ a k m o d ( p − 1 ) ( m o d p )
费马大定理:
m > 2 时, x m + y m = z m x^m + y^m = z^m x m + y m = z m 无正整数解
当m = 2 ,对于式子 a 2 + b 2 = c 2 a^2+b^2=c^2 a 2 + b 2 = c 2
(n 为任意正整数):
当 a 为奇数时:a = 2 n + 1 , c = n 2 + ( n + 1 ) 2 , b = c − 1 a=2n+1,c=n^2+(n+1)^2,b=c-1 a = 2 n + 1 , c = n 2 + ( n + 1 ) 2 , b = c − 1
当 a 为偶数时:a = 2 n + 2 , c = 1 + ( n − 1 ) 2 , b = c − 2 a=2n+2,c=1+(n-1)^2,b=c-2 a = 2 n + 2 , c = 1 + ( n − 1 ) 2 , b = c − 2
0x21.3 欧拉定理
欧拉定理
定理21.3.1 : 若正整数 a , n 互质,则 $a^{\varphi(n)}≡1(\mod\ n) 其中 其中 其 中 \varphi(n)$是欧拉函数。
推论21.3.2: ∃ x ∈ N ∗ , a x ≡ 1 ( m o d m ) ⟺ gcd ( a , m ) = 1 \exists x\in N^{*},a^x\equiv 1(\mod m) \iff \gcd(a,m)=1 ∃ x ∈ N ∗ , a x ≡ 1 ( m o d m ) ⟺ g cd( a , m ) = 1
欧拉降幂(拓展欧拉定理)
若 a 与 m 互质:
a b ≡ a b m o d φ ( m ) ( m o d m ) a^b\equiv a^{b\mod\varphi(m)}\pmod m a b ≡ a b m o d φ ( m ) ( m o d m )
若不保证 a 与 m 互质:b > φ ( m ) 时: a b ≡ a b m o d φ ( m ) + φ ( m ) ( m o d m ) b> \varphi(m) 时:a^b\equiv a^{b\mod \varphi(m)+\varphi(m)}\;\pmod m b > φ ( m ) 时 : a b ≡ a b m o d φ ( m ) + φ ( m ) ( m o d m )
在一些计数的问题中,常常要求对结果取模,但是在计算非常庞大的次幂的时候,无法直接取模,可以先把底数对 p 取模,指数对 φ ( p ) \varphi(p) φ ( p ) 取模,再计算次幂,有效地降低时间复杂度。
欧拉函数的性质
0x14 互质与欧拉函数
0x14.1 欧拉函数
定义: ∀a,b∈N 若$ gcd ( a , b ) = 1 ,$则称 a , b 互质。
对于三个数或更多的数,把gcd ( a , b , c ) = 1称之为 a , b , c 互质。
把 g c d ( a , b ) = g c d ( a , c ) = g c d ( b , c ) = 1 gcd ( a , b ) = gcd ( a , c ) = gcd ( b , c ) = 1 g c d ( a , b ) = g c d ( a , c ) = g c d ( b , c ) = 1 称之为 a , b , c 两两互质 。显然 a , b , c 两两互质是优于 a , b , c 互质的。
性质14.1.1:int 范围内的数 n 中, 1 ∼ n 1\sim n 1 ∼ n 中与 n 互质的个数最多只有1600 ( m a x { φ ( 1 ∼ 2147483647 ) } ) 1600(\quad max \{ φ ( 1 ∼ 2147483647 ) \}\quad ) 1 6 0 0 ( m a x { φ ( 1 ∼ 2 1 4 7 4 8 3 6 4 7 ) } )
欧拉函数
我们可以的到下列结论:
由算数基本定理(唯一分解定理)得
N = p 1 k 1 × p 2 k 2 × p 3 k 3 × ⋯ p m k m N= p_{1}^{k_{1}} \times p_{2}^{k_{2}} \times p_{3}^{k_{3}} \times \cdots \ p_{m}^{k_{m}}
N = p 1 k 1 × p 2 k 2 × p 3 k 3 × ⋯ p m k m
则有:
φ ( N ) = N × ∏ p ∣ N ( 1 − 1 p ) \varphi(N)=N \times \prod_{p\mid N}(1-\frac{1}{p})
φ ( N ) = N × p ∣ N ∏ ( 1 − p 1 )
其中,如果 p是素数,则φ ( p ) = p × ( 1 − 1 p ) = p − 1 φ( p) =p\times (1- \frac{1}{p}) = p-1 φ ( p ) = p × ( 1 − p 1 ) = p − 1
我们可以利用这个性质在分解质因数的同时 $ O(\sqrt n)$使用公式求解欧拉函数
1 2 3 4 5 6 7 8 9 10 11 12 inline int euler_one (int n) { int ans = n; for (int i = 2 ; i * i <= n; ++ i){ if (n % i == 0 ){ ans = ans / i * (i - 1 ); while (n % i == 0 )n /= i; } } if (n > 1 )ans = ans / n * (n - 1 ); return ans; }
由此我们得到了上面那道题的真实数据范围条件( 1 ≤ b ≤ 1 0 20000000 ) (1≤b≤10^{20000000}) ( 1 ≤ b ≤ 1 0 2 0 0 0 0 0 0 0 ) 下的a b m o d m a^b\mod m a b m o d m 的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #include <bits/stdc++.h> #define int long long using namespace std;int mod;string s; int qmul (int x,int y,int mod) { int z=(long double )x/mod*y; int res=(unsigned long long )x*y-(unsigned long long )z*mod; return (res+mod)%mod; } int qpow (int a,int b,int mod) { int ans=1 ; while (b) { if (b&1 )ans=qmul (ans,a,mod); a=qmul (a,a,mod); b>>=1 ; } return ans; } int varphi (int n) { if (n==1 )return 1 ; int ans=n; for (int i=2 ;i*i<=n;i++) { if (n%i==0 ) { ans=ans/i*(i-1 ); while (n%i==0 )n/=i; } } if (n>1 ) ans=ans/n*(n-1 ); return ans; } void EEt (int a,string b,int mod) { int b_mod=0 ; int tmod=varphi (mod); for (int i=0 ;i<b.length ();i++) { b_mod=b_mod*10 +b[i]-'0' ; if (b_mod>=tmod) { b_mod%=tmod; } } int bb=0 ; if (b.length ()<=10 )bb=stol (b,nullptr ,10 ); if (bb!=0 && bb<=tmod){printf ("%lld" ,qpow (a,bb,mod));} else { b_mod = b_mod + tmod; printf ("%lld" , qpow (a, b_mod, mod)); return ; } } signed main () { int a; scanf ("%lld %lld" ,&a,&mod); getchar (); cin>>s; EEt (a,s,mod); return 0 ; }
0x51.1 线性筛法求欧拉函数
我们注意到在线性筛中,每一个合数都是被最小的质因子筛掉,筛法求素数的同时也得到了每个数的最小质因子,这是线性筛求欧拉函数的关键。
1.考虑n = p j k , φ ( n ) n=p^k_j,\varphi(n) n = p j k , φ ( n )
显然有φ ( p j k ) = p j k − p j k − 1 = p j k − 1 × ( p j − 1 ) \varphi(p^k_j)=p^k_j-p^{k-1}_j=p_j^{k-1}\times(p_j-1) φ ( p j k ) = p j k − p j k − 1 = p j k − 1 × ( p j − 1 )
2.考虑n = i × p j n=i\times p_j n = i × p j 当p j ∣ i p_j\mid i p j ∣ i
即i i i 含有因子p j p_j p j ,由于i = n p j i=\frac{n}{p_j} i = p j n ,由唯一分解定理:
φ ( n ) = n × ∏ i = 1 s p i − 1 p i = p 1 × i × ∏ i = 1 s p i − 1 p i = p 1 × φ ( i ) \begin{aligned}
\varphi(n) & =n\times \prod_{i=1}^{s}\frac{p_i-1}{p_i} \\[2ex]
& =p_1\times i\times \prod_{i=1}^{s}\frac{p_i-1}{p_i} \\[2ex]
& =p_1\times \varphi(i)
\end{aligned}
φ ( n ) = n × i = 1 ∏ s p i p i − 1 = p 1 × i × i = 1 ∏ s p i p i − 1 = p 1 × φ ( i )
3.考虑 n = i × p j n=i\times p_j n = i × p j ,φ ( n ) \varphi(n) φ ( n ) ,当 i i i 不整除p j p_j p j
即 i i i 与 p j p_j p j 互质,积性函数显然有性质:
φ ( n ) = φ ( i ) × φ ( p j ) = φ ( i ) × ( p j − 1 ) \varphi(n)=\varphi(i)\times \varphi(p_j)=\varphi(i)\times(p_j-1)
φ ( n ) = φ ( i ) × φ ( p j ) = φ ( i ) × ( p j − 1 )
由于我们仅在在线性筛的框架上增加了一些细节,所以时间复杂度依然是O(n)的。
威尔逊定理:解决带有“!”的问题
0x21.4 威尔逊定理
威尔逊定理
定理21.4.1: 当 p 为质数时有:
( p − 1 ) ! ≡ p − 1 ≡ − 1 ( m o d p ) (p-1)!\equiv p-1\equiv -1(\mod\;p) ( p − 1 ) ! ≡ p − 1 ≡ − 1 ( m o d p ) ,
( p − 2 ) ! ≡ 1 ( m o d p ) (p-2)!\equiv 1\pmod p ( p − 2 ) ! ≡ 1 ( m o d p )
其中 定理21.4.1 实际上就等价于:若 p 是质数,则 (p−1)!+1 能够被 p 整除。
n 为素数时: ( n − 1 ) ! m o d n = 1 (n-1)!\mod n=1 ( n − 1 ) ! m o d n = 1
n 为合数时:除 n = 4 以外,( n − 1 ) ! m o d n = 0 (n-1)!\mod n=0 ( n − 1 ) ! m o d n = 0
定理21.4.2: 若一个数 p,满足条件( p − 1 ) ! + 1 (p−1)!+1 ( p − 1 ) ! + 1 可以被 p 整除,那么 p 是素数。
即:p 可整除 (p-1)!+1 是 p 为质数的充要条件。
例题:杭州电子科技大学 H D U 例题:杭州电子科技大学HDU 例 题 : 杭 州 电 子 科 技 大 学 H D U
Problem B. Fansblog(HDU 6608 19多校)
给定一个质数P ( 1 0 9 ≤ P ≤ 1 0 14 ) P(10^9≤P≤10^{14}) P ( 1 0 9 ≤ P ≤ 1 0 1 4 ) , Q 是 最大的那个小于 P 的质数,求 Q ! % P Q\ !\ \%P Q ! % P
Solution
根据威尔逊定理 ( P − 1 ) ! ≡ P − 1 ≡ − 1 ( m o d P ) (P-1)!\equiv P-1\equiv -1(\mod P) ( P − 1 ) ! ≡ P − 1 ≡ − 1 ( m o d P ) ,所以显然可以构造答案 Q !
我们知道P>Q,则有( P − 1 ) ! ≡ 1 × 2 × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × Q × ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 1 ) ≡ P − 1 ( m o d P ) (P-1)!\equiv1\times 2\times······\times Q \times (Q+1)\times······\times (P-1)\equiv P-1(\mod P) ( P − 1 ) ! ≡ 1 × 2 × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × Q × ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 1 ) ≡ P − 1 ( m o d P )
则有:Q ! ≡ P − 1 ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 1 ) ≡ 1 ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 2 ) ( m o d P ) Q!\equiv\cfrac{P-1}{(Q+1)\times······\times (P-1)}\equiv\cfrac{1}{(Q+1)\times······\times (P-2)}(\mod P) Q ! ≡ ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 1 ) P − 1 ≡ ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 2 ) 1 ( m o d P )
即求( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 2 ) (Q+1)\times······\times (P-2) ( Q + 1 ) × ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ × ( P − 2 ) 的逆元,当然目前还不会求