定理证明
引理1
若 a a a, b b b, c c c为任意3个整数 , m m m为正整数,且 ( m , c ) (m,c) (m,c)=1,则当 a ⋅ c ≡ b ⋅ c ( m o d m ) a\cdot c≡b\cdot c(mod{\space}m) a⋅c≡b⋅c(mod m) 时,有 a ≡ b ( m o d m ) a≡b(mod{\space}m) a≡b(mod m) .
证明:因为 a c ≡ b c ( m o d m ) ac≡bc(mod{\space}m) ac≡bc(mod m) ,所以 m ∣ a c − b c m|ac-bc m∣ac−bc , 即 m ∣ ( a − b ) c m|(a-b)c m∣(a−b)c , 又因为 g c d ( m , c ) = 1 gcd(m,c)=1 gcd(m,c)=1 , 所以一定有 m ∣ a − b m|a-b m∣a−b , 所以 a ≡ b ( m o d m ) a≡b(mod{\space}m) a≡b(mod m) .
引理2
设 m m m 是一个整数且 m > 1 m>1 m>1 , b b b 是一个整数且 ( m , b ) = 1 (m,b)=1 (m,b)=1 .
如果 a 1 , a 2 , a 3 , a 4 , ⋯ a m a_{1},a_{2},a_{3},a_{4},\cdots a_{m} a1,a2,a3,a4,⋯am 是模 m m m 的一个完全剩余系,则 b ⋅ a 1 , b ⋅ a 2 , b ⋅ a 3 , b ⋅ a 4 , ⋯ b ⋅ a m b\cdot a_{1},b\cdot a_{2},b\cdot a_{3},b\cdot a_{4},\cdots b\cdot a_{m} b⋅a1,b⋅a2,b⋅a3,b⋅a4,⋯b⋅am 也构成模 m m m 的一个完全剩余系。
证明:设 i ! = j i!=j i!=j ,且 ( m , b ) = 1 (m,b)=1 (m,b)=1 , b ⋅ a i ≡ b ⋅ a j ( m o d m ) b\cdot a_{i} ≡ b\cdot a_{j}(mod{\space}m) b⋅ai≡b⋅aj(mod m) .
根据引理1,则有 a 1 ≡ a j ( m o d m ) a_{1}≡a_{j}(mod{\space}m) a1≡aj(mod m) .
根据完全剩余系的定义可知这是不可能的,假设不成立 .
所以 b ⋅ a 1 , b ⋅ a 2 , b ⋅ a 3 , b ⋅ a 4 , ⋯ b ⋅ a m b\cdot a_{1},b\cdot a_{2},b\cdot a_{3},b\cdot a_{4},\cdots b\cdot a_{m} b⋅a1,b⋅a2,b⋅a3,b⋅a4,⋯b⋅am 构成模 m m m 的一个完全剩余系 .
证明
构造素数 p p p 的完全剩余系 P = { 1 , 2 , 3 , ⋯ , p − 1 } P=\{1,2,3,\cdots,p-1\} P={1,2,3,⋯,p−1} .
因为 ( a , p ) = 1 (a,p)=1 (a,p)=1 , 有引理2得 A = { a , 2 a , 3 a , ⋯ , ( p − 1 ) a } A=\{a,2a,3a,\cdots,(p-1)a\} A={a,2a,3a,⋯,(p−1)a} 也是素数 p p p 的一个完全剩余系 .
由完全剩余系的性质可得
1
×
2
×
3
×
⋯
×
(
p
−
1
)
≡
a
×
2
a
×
3
a
×
⋯
×
(
p
−
1
)
a
(
m
o
d
p
)
1\times2\times3\times\cdots\times(p-1)≡a\times2a\times3a\times\cdots\times(p-1)a\space(mod\space p)
1×2×3×⋯×(p−1)≡a×2a×3a×⋯×(p−1)a (mod p)
即 ( p − 1 ) ! ≡ ( p − 1 ) ! ⋅ a p − 1 ( m o d p ) (p-1)!≡(p-1)!\cdot a^{p-1}\space(mod\space p) (p−1)!≡(p−1)!⋅ap−1 (mod p) .
易知 g c d ( ( p − 1 ) ! , p ) = 1 gcd((p-1)!,p)=1 gcd((p−1)!,p)=1 ,两边同时约去 ( p − 1 ) ! (p-1)! (p−1)! ,得 a p − 1 ≡ 1 ( m o d p ) a^{p-1}≡1\space(mod\space p) ap−1≡1 (mod p) .
费马小定理获证 .
例题
P2613 【模板】有理数取余
题目描述
给出一个有理数 c = a b c=\frac{a}{b} c=ba,求 c c c m o d mod mod 19260817 的值。
这个值被定义为 b x ≡ a ( m o d 19260817 ) bx≡a\space(mod\space19260817) bx≡a (mod 19260817) 的解。
输出一个整数,代表求余后的结果。如果无解,输出 Angry!。
对于所有数据,保证 0 ≤ a ≤ 1 0 10001 0≤a≤10^{10001} 0≤a≤1010001, 1 ≤ b ≤ 1 0 10001 1≤b≤10^{10001} 1≤b≤1010001 ,且 a , b a,b a,b 不同时是 19260817 的倍数。
解题思路
先考虑 a a a 为模数倍数的时候,由于 a , b a,b a,b 不可能同时为模数的倍数,此时一定存在 b b b 的乘法逆元, a n s ans ans 可以看做是 a a a 乘上 b b b 的乘法逆元再取模,答案为 0 0 0 ;
接着再考虑 b b b为模数倍数的时候,此时不存在 b b b 的乘法逆元,输出 A n g r y ! Angry! Angry! ;
最后在考虑 a , b a,b a,b 均不是模数倍数的时候,此时也存在 b b b 的乘法逆元, a n s ans ans 同样可以看做是 a a a 乘上 b b b 的乘法逆元再取模,可以先用费马小定理求出 b b b 的乘法逆元,乘上 a a a 输出即可 。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=19260817;
namespace zyx_{
ll read(){
ll x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+(c^48);
x%=mod;
c=getchar();
}
return x;
}
ll a,b;
ll gcd(ll x,ll y){
if(x<y) swap(x,y);
return y==0?x:gcd(y,x%y);
}
ll qpow(ll x,ll y){
ll res=1;
while(y){
if(y&1) (res*=x)%=mod;
y>>=1;
(x*=x)%=mod;
}
return res;
}
int my_main(){
a=read(),b=read();
if(a%gcd(b,mod)!=0) cout<<"Angry!";
else cout<<(a*qpow(b,mod-2))%mod;
return 0;
}
}
int main(){
zyx_::my_main();
return 0;
}
P1593 因子和
题目描述
输入两个整数 a , b a,b a,b,求 a b a^b ab 的因子和。
由于结果太大,只要输出它对 9901 取模的结果。
解题思路
由算数基本定理,将 a a a 进行质因数分解 a = p 1 c 1 ⋅ p 2 c 2 ⋯ p k c k a=p_{1}^{c1} \cdot p_{2}^{c2} \cdots p_{k}^{ck} a=p1c1⋅p2c2⋯pkck ;
那么 a b = ( p 1 c 1 ⋅ p 2 c 2 ⋯ p k c k ) b = p 1 c 1 ⋅ b ⋅ p 2 c 2 ⋅ b ⋯ p k c k ⋅ b a^b=(p_{1}^{c1} \cdot p_{2}^{c2} \cdots p_{k}^{ck})^b=p_{1}^{c1\cdot b} \cdot p_{2}^{c2\cdot b} \cdots p_{k}^{ck\cdot b} ab=(p1c1⋅p2c2⋯pkck)b=p1c1⋅b⋅p2c2⋅b⋯pkck⋅b ;
σ ( k ) = ( 1 + p 1 + p 1 2 + ⋯ + p 1 c 1 ⋅ b ) ⋅ ( 1 + p 2 + p 2 2 + ⋯ + p 2 c 2 ⋅ b ) ⋅ ⋯ ⋅ ( 1 + p k + p k 2 + ⋯ + p k c k ⋅ b ) σ(k) = (1 + p_{1} + p_{1}^{2} + \cdots + p_{1}^{c1\cdot b}) \cdot (1 + p_{2} + p_{2}^{2} + \cdots + p_{2}^{c2\cdot b}) \cdot \cdots \cdot (1 + p_{k} + p_{k}^{2} + \cdots + p_{k}^{ck\cdot b}) σ(k)=(1+p1+p12+⋯+p1c1⋅b)⋅(1+p2+p22+⋯+p2c2⋅b)⋅⋯⋅(1+pk+pk2+⋯+pkck⋅b) ;
发现 1 + p i + p i 2 + ⋯ + p i c i ⋅ b 1 + p_{i} + p_{i}^{2} + \cdots + p_{i}^{ci\cdot b} 1+pi+pi2+⋯+pici⋅b 为等比数列 ;
根据等比数列求和公式,则 S i = 1 × p i c i ⋅ b + 1 − 1 p i − 1 \large S_{i}=1\times \frac{p_{i}^{ci\cdot b + 1}-1}{p_{i}-1} Si=1×pi−1pici⋅b+1−1 ;
若 p i ≡ 1 ( m o d 9901 ) p_{i}≡1(mod\space 9901) pi≡1(mod 9901) ,则不存在 p i − 1 p_{i}-1 pi−1 的乘法逆元 ,需要特殊处理 ;
再这样的等比数列中,每一项都有 p j ≡ 1 ( m o d 9901 ) p_{j}≡1(mod\space 9901) pj≡1(mod 9901) ,那么 S j ≡ n + 1 ( m o d 9901 ) S_{j}≡n+1(mod\space 9901) Sj≡n+1(mod 9901) ;
其余情况只需要分别求出 p i c i ⋅ b + 1 − 1 p_{i}^{ci\cdot b + 1}-1 pici⋅b+1−1 与 p i − 1 p_{i}-1 pi−1 的逆元计算即可 ;
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int mod=9901;
namespace zyx_{
ll read(){
ll x=0;int f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
ll a,b,ans=1,cnt,p[N],c[N];
void getp(){
ll n=a;
for(int i=2;i<=n;i++){
if(n%i) continue;
p[++cnt]=i;
while(n%i==0) c[cnt]++,n/=i;
}
if(n>1) p[++cnt]=n,c[cnt]=1;
for(int i=1;i<=cnt;i++) c[i]*=b;
return ;
}
ll qpow(ll x,ll y){
ll res=1;
while(y){
if(y&1) (res*=x)%=mod;
y>>=1;
(x*=x)%=mod;
}
return res;
}
void getans(){
for(int i=1;i<=cnt;i++){
int k=c[i];
if(p[i]>mod&&p[i]%mod==1){
(ans*=(k+1))%=mod;
continue;
}
(ans*=(qpow(p[i],k+1)-1))%=mod;
(ans*=qpow(p[i]-1,mod-2))%=mod;
}
return ;
}
int my_main(){
a=read(),b=read();
getp();
getans();
cout<<(ans%mod+mod)%mod;
return 0;
}
}
int main(){
zyx_::my_main();
return 0;
}
8883

被折叠的 条评论
为什么被折叠?



