质数

本文介绍了模p运算的基本概念,包括取模运算、模p加法、减法及乘法,并探讨了这些运算的性质。同时,文章还讨论了模p相等的概念及其与普通四则运算的区别,并给出了欧拉函数、欧拉定理和费马定理的相关证明。

模p运算

给定一个正整数p,任意一个整数n,一定存在等式

          n = kp + r

其中k、r是整数,且 0 ≤ r < p,称呼k为n除以p的商,r为n除以p的余数。

对于正整数p和整数a,b,定义如下运算:

  • 取模运算:a mod p 表示a除以p的余数。
  • 模p加法:(a + b) mod p ,其结果是a+b算术和除以p的余数,也就是说,(a+b) = kp +r,则 (a+b) mod p = r。
  • 模p减法:(a-b) mod p ,其结果是a-b算术差除以p的余数。
  • 模p乘法:(a × b) mod p,其结果是 a × b算术乘法除以p的余数。

可以发现,模p运算和普通的四则运算有很多类似的规律,如:

规律公式
结合率((a+b) mod p + c)mod p = (a + (b+c) mod p) mod p
((a*b) mod p * c)mod p = (a * (b*c) mod p) mod p
交换率(a + b) mod p = (b+a) mod p
(a × b) mod p = (b × a) mod p
分配率((a +b)mod p × c) mod p = ((a × c) mod p + (b × c) mod p) mod p

简单的证明其中第一个公式:

 ((a+b) mod p + c) mod p = (a + (b+c) mod p) mod p
假设
a = k1 p + r1
b = k2 p + r2
c = k3 p + r3

a+b = (k1 + k2) p + (r1 + r2)
如果(r1 + r2) >= p ,则
(a+b) mod p = (r1 + r2) -p
否则
(a+b) mod p = (r1 + r2)
再和c进行模p和运算,得到
结果为 r1 + r2 + r3的算术和除以p的余数。
对右侧进行计算可以得到同样的结果,得证。

模p相等

如果两个数a、b满足a mod p = b mod p,则称他们模p相等,记做

 a ≡ b mod p
可以证明,此时a、b满足 a = kp + b,其中k是某个整数。

对于模p相等和模p乘法来说,有一个和四则运算中迥然不同得规则。在四则运算中,如果c是一个非0整数,则

       ac = bc 可以得出  a =b

但是在模p运算中,这种关系不存在,例如:

 (3 x 3) mod 9 = 0
(6 x 3) mod 9 = 0
但是
3 mod 9 = 3
6 mod 9 =6

定理(消去律):如果gcd(c,p) = 1 ,则 ac ≡ bc mod p 可以推出 a ≡ b mod p

 证明:
因为ac ≡ bc mod p
所以ac = bc + kp,也就是c(a-b) = kp
因为c和p没有除1以外的公因子,因此上式要成立必须满足下面两个条件中的一个
1) c能整除k
2) a = b
如果2不成立,则c|kp
因为c和p没有公因子,因此显然c|k,所以k = ck'
因此c(a-b)kp可以表示为c(a-b) =ck'p
因此a-b = k'p,得出a ≡ b mod p
如果a = b,则a ≡ b mod p 显然成立
得证

欧拉函数

欧拉函数是数论中很重要的一个函数,欧拉函数是指:对于一个正整数n,小于n且和n互质的正整数的个数,记做:φ(n),其中φ(1)被定义为1,但是并没有任何实质的意义。

定义小于n且和n互质的数构成的集合为Zn,称呼这个集合为n的完全余数集合。

显然,对于素数p,φ(p)= p -1.对于两个素数p、q,他们的乘积n = pq 满足φ(n) =(p-1)(q-1)

        证明:对于质数p,q,满足φ(n) =(p-1)(q-1)
考虑n的完全余数集Zn = { 1,2,....,pq -1}
而不和n互质的集合由下面三个集合的并构成:
1) 能够被p整除的集合{p,2p,3p,....,(q-1)p} 共计q-1个
2) 能够被q整除的集合{q,2q,3q,....,(p-1)q} 共计p-1个
3) {0}
很显然,1、2集合中没有共同的元素,因此Zn中元素个数 = pq - (p-1 + q- 1 + 1) = (p-1)(q-1)

欧拉定理

对于互质的整数a和n,有aφ(n) ≡ 1 mod n

        证明:
首先证明下面这个命题:
对于集合Zn={x1,x2,...,xφ(n)},考虑集合
S = {ax1 mod n,ax2mod n,...,axφ(n)mod n}
则S = Zn

1) 由于a,n互质,xi也与n互质,则axi也一定于p互质,因此
任意xi,axi mod n 必然是Zn的一个元素
2) 对于Zn中两个元素xi和xj,如果xi ≠ xj
则axi mod n ≠ axi mod n,这个由a、p互质和消去律可以得出。
所以,很明显,S=Zn

既然这样,那么
(ax1 × ax2×...×axφ(n))mod n
= (ax1 mod n × ax2mod n × ... × axφ(n)mod n)mod n
= (x1 × x2 × ... × xφ(n))mod n
考虑上面等式左边和右边
左边等于(aφ(n) × (x1 × x2 × ... × xφ(n))mod n) mod n
右边等于x1 × x2 × ... × xφ(n))mod n
而x1 × x2 × ... × xφ(n))mod n和p互质
根据消去律,可以从等式两边约去,就得到:
aφ(n) ≡ 1 mod n
推论:对于互质的数a、n,满足aφ(n)+1 ≡ a mod n

费马定理


a是不能被质数p整除的正整数,则有ap-1 ≡ 1 mod p


证明这个定理非常简单,由于φ(p) = p-1,代入欧拉定理即可证明。


同样有推论:对于不能被质数p整除的正整数a,有ap ≡ a mod p

 
明白了!你说的“不是质数是素数”,应该是说: > 判断一个数是否是**素数(质数)**,而不是合数。 我们来重新梳理一下你的原始代码意图: 你希望判断一个数是否是**素数**(即质数),而你的函数 `haha` 实际上是判断一个数是否是**合数**(非质数),所以逻辑是反的。 --- ## ✅ 正确判断素数的函数(优化版) ```c #include <stdio.h> #include <stdbool.h> #include <math.h> // 判断一个数是否为素数 bool is_prime(int a) { if (a < 2) return false; // 0和1都不是素数 int sqrt_a = (int)sqrt(a); // 只需要检查到平方根即可 for (int i = 2; i <= sqrt_a; i++) { if (a % i == 0) return false; // 能整除则不是素数 } return true; } ``` > **说明**: - 时间复杂度从原来的 `O(a/2)` 优化到 `O(√a)`。 - 更加高效,尤其在处理大数时提升明显。 --- ## ✅ 修正主函数逻辑 你原来的主函数中,有一个 `while(k--)` 的写法是错误的,因为 `k` 是在循环中被递减的,导致第一次循环后 `k` 就变成 0,后续循环无法再进入。 我们来修正整个逻辑,使用**滑动窗口**或**前缀和**来高效地处理连续 `k` 个元素的和。 ### ✅ 改进后的完整代码 ```c #include <stdio.h> #include <stdbool.h> #include <math.h> bool is_prime(int a) { if (a < 2) return false; int sqrt_a = (int)sqrt(a); for (int i = 2; i <= sqrt_a; i++) { if (a % i == 0) return false; } return true; } int main() { int n, k; scanf("%d%d", &n, &k); int a[n]; // 输入数组 for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } int count = 0; // 对每个起点 i,计算连续 k 个元素的和(循环数组) for (int i = 0; i < n; i++) { int sum = 0; for (int j = 0; j < k; j++) { int index = (i + j) % n; // 循环取数 sum += a[index]; } if (is_prime(sum)) { count++; } } printf("%d\n", count); return 0; } ``` > **说明**: - `is_prime` 函数用于判断和是否是素数。 - 每次从位置 `i` 开始,取 `k` 个元素(循环数组),求和后判断是否为素数。 - 总时间复杂度为 `O(n * k + n * √sum)`,在合理范围内。 --- ## ✅ 示例 输入: ``` 5 2 2 3 5 7 11 ``` 输出: ``` 5 ``` 说明:所有连续两个数的和都是素数。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值