##### 题目描述
在算法竞赛中你会遇到各种各样的有关素数的问题,今天你来解决一个最基础的问题:如何判定一个素数。 对于给定的正整数p,若p非素数,输出-1 若p是素数 输出 :{sigma(a^(p-1) % p) ,其中a的下界为1,上界为p-1}
即:
~~~[math]
\sum_{a=1}^{p-1}({a^{p-1}\%p})
~~~
**输入**
多实例测试,每组数据包含一个正整数p(p < 10^16)。
**输出**
根据情况输出一个正整数,保证答案在int64之内,输出占一行。
**样例输入**
2
**样例输出**
1
这个题一般方法是就是暴力求解了,首先判断是不是素数,如果不是素数,那么输出-1,如果是素数,那么就实处上面那个式子的值。
但是题目要求的数据范围为1e16,如果我们用一般判断素数的方法(sqrt(n))去求解的话,必定会超时,那么我们如何解决这个问题呢,费马小定理出现了。
> 费马小定理 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),例如:假如a是整数,p是质数,则a,p显然互质(即两者只有一个公约数1),那么我们可以得到费马小定理的一个特例,即当p为质数时候, a^(p-1)≡1(mod p)。
因此,我们可以随机几个数字(与p互质),如果a^(p-1)≡1(mod p)对这些数字恒成立,那么p就是一个质数。
一般情况下,我们只需要列举十个左右的数字即可确定一个数字是否为质数。
代码如下:
~~~
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll mulpow(ll a,ll x)
{
ll res=1;
while(x){
if(x&1) res=res*a%n;
a=a*a%n;
x>>=1;
}
return res;
}
int main()
{
ll t,i;
//以下是我自己列举的一些随机数,我们也可以用一些随机数函数来找一些随机数
ll a[20]={7,43,64,69,87,31,45,72,81,79,47,33,43,97,121,199,173,153,157,53};
while(~scanf("%lld",&n)){
for(i=0;i<20;i++){
if(gcd(a[i],n)==1 && mulpow(a[i],n-1)!=1){//两个判断条件,两个数字互质且符合费马小定理
break;
}
}
if(i==20){
printf("%lld\n",n-1);
}
else
printf("-1\n");
}
return 0;
}
~~~
用以上方法即可迅速判断一个数是否是质数,对特别大的数字尤其适用。
- 简介
- 零基础快速入门ACM
- C语言快速入门
- C语言快速入门
- C/C++基础
- 输入输出
- 数组和字符串
- 数组
- 字符数组
- 函数和递归
- C++标准容器库(STL)
- Vector
- Map
- Set
- String
- Stack
- Queue
- Priority_queue
- 贪心
- 硬币问题
- 区间调度问题
- 字典序最小问题
- 独木舟问题
- 搜索
- DFS
- BFS
- 剪枝
- 记忆化搜索
- 常用技巧
- 倍增
- 高精度
- 大数加法
- 大数减法
- 大数乘法
- 大数除法
- 大数阶乘
- 输入挂
- 前缀和
- 二分
- 本地预处理
- 尺取
- 枚举
- 坐标离散化
- 分治
- 数列分治
- 树上分治
- 平面分治
- 计算几何
- 凸包
- 点积
- 叉积
- 线段关系
- 皮克定理
- 最近点对
- 数据结构
- 线段树
- 树状数组
- 并查集
- 动态规划
- 基础知识
- 信息学竞赛中的动态规划
- 动态规划初步
- 最长上升子序列(LIS)
- 最长公共子序列(LCS)
- 最大子段和
- 背包问题
- 部分背包
- 0 1 背包
- 完全背包
- 多重背包
- 背包的可行性问题
- 线性DP
- 树形DP
- 区间DP
- 数位DP
- 动态规划优化
- 字符串
- KMP算法
- 拓展KMP
- 字符串Hash
- Manacher算法
- 后缀数组
- Trie树
- 博弈论
- Nim博弈
- Bash博弈
- 斐波那契博弈
- 威佐夫博弈
- SG函数
- 数论
- 整数研究
- 素数判断
- 素数筛选
- 快速幂
- 算数基本定理
- 最大公约数(Gcd)
- 费马小定理
- 扩展欧几里得
- 逆元
- 同余定理
- 组合数学
- 容斥原理
- 抽屉原理
- 卢卡斯(Lucas)
- 卡特兰(Catalan)
- 著名函数
- 欧拉函数
- 莫比乌斯函数
- 线性代数
- 矩阵运算
- 矩阵快速幂
- 图论
- 存图方法
- 邻接矩阵
- 邻接表
- Vector存图
- 链式前向星
- 图的遍历
- 拓扑排序
- 最短路
- Dijkstra算法
- SPFA算法
- Floyed 算法
- 最小生成树
- Prim算法
- Kruskal算法
- 最近公共祖先 (LCA)
- 二分图匹配
- 网络流
- 其他
- 莫队