1.同余与模运算
记得公式(a-b)mod n=[(a mod n)-(b mod n) +n]mod n;这里(a mod n)-(b mod n)可能小于0故要+n;
ab mod n=(long long) ( a mod n ) * ( b mod n ) mod n; 乘法结果可能溢出,所以要强制类型转换;
2.UVA上的10006题就用了这个技术;http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=947
题目大意,一个2<n<65000,如过对于每一个2<a<n-1,都有a^n mod n=a;并且a不是素数 那么a就是Carmichael number否则就是normal;
分析:这个题目,有两个条件(1)非素数;(2)满足同余表达式;故可用面向过程的想法,来分解这个题目
1 // vsversion.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 6 /************************************************************************/ 7 /*首先构造素数表,然后每次读取一个数据,查表有的话normal; 8 然后使用快速幂技术,a从2到n-1进行快速幂;如果过程中有值不符合,那么就normal 9 否则就说是那种数; 10 */ 11 /************************************************************************/ 12 #include <cstdio> 13 #include <iostream> 14 #include <cstring> 15 #include<cmath> 16 using namespace std; 17 #define MAX 65000 18 int prime_list[MAX+10]; 19 void Init_prime_list(int n) 20 {//找出小于n的所有素数; 21 22 23 //使用去倍数法; 24 memset(prime_list,-1,sizeof prime_list); 25 for (int i=2;i*i<=n;i++) 26 { 27 for (int j=i*i;j<=n && prime_list[i]==-1;j+=i) 28 { 29 prime_list[j]=0;//非素数是1; 30 } 31 } 32 33 } 34 35 36 /* 37 int pow_mod(int a,int n,int m) 38 { 39 if(n==1) return a%m; 40 unsigned ans=pow_mod(a,n/2,m); 41 ans=(ans*ans)%m; 42 if(n%2==1) return ans*a%m; 43 return ans; 44 }*/ 45 int pow_mod(int a,int n,int m) 46 { 47 if (n==1) 48 return a%m; 49 unsigned x=pow_mod(a,n/2,m); 50 unsigned ans=(x*x) %m; 51 if (n%2==1)ans=(ans*a)%m; 52 return (int)ans%m; 53 } 54 bool text(int n) 55 { 56 //首先判断是否是素数 57 if (prime_list[n]) 58 { 59 //cout<<n<<" is normal.\n"; 60 return false; 61 } 62 //如果不是素数接着快速幂; 63 for (int i=2;i<n;i++) 64 { 65 if (pow_mod(i,n,n)!=i) 66 return false; 67 } 68 return true; 69 70 } 71 72 73 #ifndef ONLINE_JUDGE 74 int _tmain(int argc, _TCHAR* argv[]) 75 #else 76 int main() 77 //fstream cin("F://code//txt//33.txt"); 78 #endif 79 //int main() 80 { 81 /*读取数据*/ 82 #ifndef ONLINE_JUDGE 83 freopen("F://code//txt//33.txt","r",stdin); 84 //fstream cin("F://code//txt//33.txt"); 85 #endif 86 //创建素数表; 87 Init_prime_list(MAX); 88 int n; 89 cin>>n; 90 while(n) 91 { 92 //memset(prime_list,0,sizeof prime_list); 93 //进行检测//检测结果分析,做出决定; 94 if (text(n)) 95 { 96 //cout<<"The number "<<n<<" is a Carmichael number.\n"; 97 printf("The number %d is a Carmichael number.\n",n); 98 99 } 100 else 101 { 102 //cout<<n<<" is normal.\n"; 103 printf("%d is normal.\n",n); 104 105 } 106 107 108 //读取下一个n; 109 cin>>n; 110 } 111 //system("pause"); 112 return 0; 113 114 }