快速冪取模+費瑪小定理
冪運算有n多次乘法,是很耗時的,所以就有了快速冪這種東西,但是冪很容易爆掉,所以一般就有了快速冪取模,實現就套模板
就好了,但是重在理解,原理跟二進制的位運算有關...
而費瑪小定理則看下面這一題,雖然這題跟費瑪小定理並沒有什麼關係,就是快速冪而已,但是涉及到了定義,看一下很是好的!
畢竟以後會用到吧...
這題很簡單,就判斷一次素數,再快速冪取模判斷一次,就秒了,快速冪雖然很久沒寫,但是還是勉強寫出來;
莫名的WA原來是long long的問題,太坑了,本來題目給的p是int就夠的,但是傳參的時候都要改成long long:
1 // poj 1845.Sumdiv 2 // 费马小定理 + 快速幂 3 // references: 4 // http://blog.csdn.net/u013021513/article/details/47361719 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 #include <algorithm> 9 10 using namespace std; 11 12 bool isPrime(int x) 13 { 14 if(x == 0 || x == 1) return 0; 15 for(int i=2; i*i<=x; i++) 16 if(x % i == 0) 17 return 0; 18 return 1; 19 } 20 21 //快速幂取模模板 22 long long quick_mod(long long a, long long p) 23 { 24 long long k = p; //mod的数不能变 25 long long ans = 1; 26 while(p) 27 { 28 if(p & 1) 29 ans = (ans * a) % k; 30 a = (a * a) % k; 31 p /= 2; 32 } 33 return ans; 34 } 35 36 int main() 37 { 38 int a, p; 39 while(scanf("%d%d", &p, &a) != EOF, p, a) 40 { 41 if(isPrime(p)) 42 { 43 printf("no\n"); 44 continue; 45 } 46 47 long long ans = quick_mod(a, p); 48 //printf("%lld\n", ans); 49 if(ans % p == a) 50 { 51 printf("yes\n"); 52 } 53 else 54 printf("no\n"); 55 } 56 return 0; 57 }