2^x mod n = 1
InputOne positive integer on each line, the value of n.
OutputIf the minimum x exists, print a line with 2^x mod n = 1.
Print 2^? mod n = 1 otherwise.
You should replace x and n with specific numbers.
Sample Input
2 5
Sample Output
2^? mod 2 = 1 2^4 mod 5 = 1
#include <cstdio> int Powermod(int a,int b,int c) { int ans=1; a=a%c; while (b) { if (b&1) ans=ans*a%c; a=a*a%c; b>>=1; } return ans; } int main() { int n; while (~scanf("%d",&n)) { if (n%2==0||n==1) { printf("2^? mod %d = 1\n",n); continue; } for (int i=1;;i++) { if (Powermod(2,i,n)==1) { printf("2^%d mod %d = 1\n",i,n); break; } } } return 0; }
这道题虽然题目字少,但是对于数论的初学者来说还是有难度的。因为这道题目涉及到了快速幂加上同余模的算法,代码中的核心部分Powermod是一个比较简洁的写法,还有一些比较清晰但是代码量多的写法。
这里附上代码以及推荐阅读的博客:
private static int cifang3(int a, int b) { int s = 1; while (b > 0) { if (b % 2 == 1) { s = s % 1000; a = a % 1000; s = s * a; } a = a % 1000; a = a * a; b = b >> 1; } return s% 1000; }
https://blog.csdn.net/java_c_android/article/details/55802041
这个博客写得很清楚了,对于同余定理和快速幂不熟悉的同学们可以阅读一下。
对于同余定理的理解,我只说最后一行是怎么得来的,你可以看到第一行的末尾,已经存在两数乘积然后模m的形式了,这时候就直接将a%m看成一个整体,套用同余定理的公式就可以了。
这个东西最好记住,不然题目没法理解,真的。
对于快速幂来说,你可以把他们想象成一个一个待处理的瓜子一样,需要挨个地嗑。首先把他转换成二进制,这时候你就可以看到,哪些位是需要计算,哪些位是不需要计算的了。
对于乘的倍数来说,这是满算,所以当一位上有一的时候,你得照着它本来的值进行计算,而不是按照进制幂指数减一再乘。这基本上就是同余模和快速幂了。
至于同余模加快速幂你最好有个抽象的理解,也可以一步一步的演算,虽然这样也可能理解不了本质,所以抽象一点,我算的就是同余定理,我要的也是他的同余数,只要按照正确的式子j进行
计算就能得到正确的答案,前提是代码得出的式子是建立的同余定理的基础上的,具体详见第一块代码的Powermod部分。