一.基本理论
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;
}