一.基本理论
1.基本概念:
给定一个正整数p,任意一个整数n,一定存在等式 n=kp+r
其中 k、r是整数,且 0≤r<p,称呼 k为 n除以 p的商, r为 n除以p的余数。
对于正整数p和整数 a,b,定义如下运算:
取模运算: a%p(或amodp),表示a除以p的余数。
模p加法: (a+b)%p ,其结果是 a+b算术和除以p的余数,也就是说, (a+b)=kp+r,则 (a+b)%p=r。
模p减法: (a−b)%p,其结果是 a−b算术差除以p的余数。
模p乘法: (a∗b)%p,其结果是 a∗b算术乘法除以p的余数。
2.说明:
1. 同余式:正整数 a,b 分别对 p 取模,它们的余数相同,记做 a≡b%p或者 a≡b(modp)。
2. n%p得到结果的正负由被除数n决定,与p无关。例如: 7%4=3, −7%4=−3,7%−4=3,−7%−4=−3。
3.基本性质
(1)若 p∣(a−b),则 a≡b(%p)。例如 11≡4(%7), 18≡4(%7)
(2) (a%p)=(b%p)意味 a≡b(%p)
(3)对称性: a≡b(%p)等价于 b≡a(%p)
(4)传递性:若 a≡b(%p)且 b≡c(%p),则 a≡c(%p)
运算规则
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a+b)%p=(a%p+b%p)%p (1)
(a−b)%p=(a%p−b%p)%p (2)
(a∗b)%p=(a%p∗b%p)%p (3)
(ab)%p=((a%p)b)%p (4)
结合率: ((a+b)%p+c)%p=(a+(b+c)%p)%p(5)
((a∗b)%p∗c)%p=(a∗(b∗c)%p)%p (6)
交换率: (a+b)%p=(b+a)%p (7)
(a∗b)%p=(b∗a)%p (8)
分配率: ((a+b)%p∗c)%p=((a∗c)%p+(b∗c)%p)%p (9)
**重要定理:**若 a≡b(%p),则对于任意的 c,都有 (a+c)≡(b+c)(%p);(10)
若 a≡b(%p),则对于任意的 c,都有 (a∗c)≡(b∗c)(%p);(11)
若 a≡b(%p), c≡d(%p),则 (a+c)≡(b+d)(%p), (a−c)≡(b−d)(,
(a∗c)≡(b∗d)(%p), (a/c)≡(b/d)(%p); (12)
若 a≡b(%p),则对于任意的 c,都有 ac≡bc(%p); (13)
二.基本应用
1.判别奇偶数 2.判别素数3. 最大公约数 4.模幂运算
1.快速幂运算
UVA10006 Carmichael Numbers
一个数是 CarmichaelNumbers
得满足它不是质数并且对于每一个 i(1<i<n)都满足 in≡imodn
我们如果暴力求解 in
时间复杂度是 O(n)妥妥的 TLE
我们引进一个高效求 xy 的东西:
快速幂
什么是快速幂呢,就是把 xy
变为
(1) ymod2=0:xy=(x2)y/2(
(2) ymod2=1:xy=x∗xy−1 ,此时y为偶数
因为每次 y 都会除以2
所以快速幂的时间复杂度就为 O(log2y)
那么此题的时间复杂度就为 O(T∗(n+n∗log2n))
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ifstream in("input.txt");
ofstream out("output.txt");
#define debug(x) cout<<"# "<<x<<endl
const ll N=100005;
const ll base=137;
const ll mod=2147483647;
const ll INF=1<<30;
ll n,m,x;
ll mod_pos(ll x,ll n,ll mod)
{
ll res=1;
while(n)
{
if(n&1)res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
}
int main()
{
while(~scanf("%lld",&n)&&n!=0)
{
bool flag=true;
for(int i=2;i*i<=n;++i){
if(n%i==0)
flag=false;
}
if(flag){
printf("%lld is normal.\n",n);
continue;
}
flag=true;
for(int i=2;i<n;++i)
{
if(mod_pos(i,n,n)!=i){
flag=false;
printf("%lld is normal.\n",n);
break;
}
}
if(flag)printf("The number %lld is a Carmichael number.\n",n);
}
return 0;
}