题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1905
题目大意:a^p≡a(mod p)成立,前提条件是p是素数,a是整数(本质是费马小定理),现在有一些数p,他不是素数,但是仍然有a^p≡a(mod p)成立,这个p就是伪素数(Pseudoprime)。现在给出p,a的值,求p是不是伪素数。
要判断是不是素数,伪素数一定不是素数。然后用快速幂计算a^p≡a(mod p)是否成立。
快速幂有递归和非递归两种
这里的b>>1就是b/=2,但是位运算更接近计算机底层计算方式,会更快一点。
int quickpow(int a,int b) //递归
{
if(b==1) return a;
if(b&1)
{
int t = quickpow2(a,b>>1);
return t*t*a;
}
else
{
int t = quickpow2(a,b>>1);
return t*t;
}
}
int quickpow(int a,int b) //非递归
{
int ans = 1;
while(b)
{
if(b&1) ans = ans*a; //n&1 相当于 n%2
a = a*a;
b >>= 1; //相当于n/2
}
return ans;
}
如果在求快速幂的过程中,每一步都添加取余,就会得到a^b(mod n)的结果
int quickpow(int a,int b,int n) //递归
{
if(b==1) return a;
if(b&1)
{
int t = quickpow2(a,b>>1,n);
t = t*t%n;
return t*a%n;
}
else
{
int t = quickpow2(a,b>>1,n);
return t*t%n;
}
}
int quickpow1(int a,int b,int n) //非递归
{
int ans = 1;
while(b)
{
if(b&1) ans = ans*a%n;
a = a*a%n;
b >>= 1;
}
return ans;
}
先判断是不是素数,如果是直接no;如果不是,在用快速幂计算a^p≡a(mod p)是不是成立,如果成立yes,如果不成立no。
#include<iostream>
using namespace std;
typedef long long ll;
ll quickpow(ll a,ll b,ll n)
{
ll ans = 1;
while(b)
{
if(b&1) ans = ans*a%n;
a = a*a%n;
b >>= 1;
}
return ans;
}
int isPrime(ll x)
{
for(ll i=2;i*i<=x;i++)
if(x%i==0) return 0;
return 1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
ll p,a;
while(cin>>p>>a)
{
if(!p&&!a) return 0;
if(isPrime(p))
{
cout<<"no\n";
continue;
}
if(quickpow(a,p,p)==a)
{
cout<<"yes\n";
continue;
}
else
{
cout<<"no\n";
continue;
}
}
return 0;
}