数论

1.快速幂:

 

Calculate 

  R := a ^ n mod m 

  1. #include <stdio.h>  
  2.   
  3. typedef unsigned long long ULL;  
  4.   
  5. // 快速模幂计算函数  
  6. ULL powermod(ULL a, ULL n, ULL m)  
  7. {  
  8.    ULL res = 1;  
  9.     while(n) {  
  10.         if(n & 1) {        // n % 2 == 1  
  11.             res *= a;  
  12.             res %= m;  
  13.         }  
  14.         a *= a;  
  15.         a %= m;  
  16.         n >>= 1;  
  17.     }  
  18.   
  19.     return res;  
  20. }  

 

2.素数判定:

 

 

  1. #include <stdio.h>  
  2. #include <math.h>  
  3. int isprime(int n)  
  4. {  
  5.     if(n == 3)  
  6.         return 1;  
  7.     int temp, i;  
  8.     temp = n % 6;                          // n%6余数有6个:0,1,2,3,4,5,若为0,2,3,4,都不是素数;为1,5,是素数
  9.     if(temp != 1 && temp != 5)  
  10.         return 0;  
  11.     temp = sqrt(n);  
  12.     for(i=3; i<=temp; i+=2)  
  13.         if(n % i == 0)  
  14.             return 0;    
  15.     return 1;  
  16. }  
  17.   

 

3.筛选法:

 

 

  1. const int N = 1e6;  
  2. const int SQRTN = ceil(sqrt((double) N));   //ceil 返回大于或等于()内值得最小整数
  3. bool isPrime[N + 1];  
  4. int prefixsum[N + 1];  
  1.   bool isPrime[N + 1]; 
  2. // Eratosthenes筛选法  
  3. void esieve(void)  
  4. {  
  5.     memset(isPrime, truesizeof(isPrime));  
  6.   
  7.     isPrime[0] = isPrime[1] = false;  
  8.     pcount = 0;  
  9.     for(int i=2; i<=N; i++) {  
  10.         if(isPrime[i]) {  
  11.             prime[pcount++] = i;  
  12.   
  13.             for(int j=i*i; j<=N; j+=i)  //筛选  
  14.                 isPrime[j] = false;  
  15.         }  
  16.     }  
  17. }  

 

4.模除:

 

斐波拉契数列: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2)

思想:f(n)(mod 3)≡(f(n-2)+f(n-1))(mod 3)≡(f(n-2)(mod 3) + f(n-1)(mod 3))(mod 3)

若对于正整数k和m,若f(k-2)=f(m-2)且f(k-1)=f(m-1),则f(k)=f(k-2)+f(k-1)=f(m-2)+f(m-1)=f(m),即如果k和m的前两项完全相同,则f(k)=f(m)。这样的数列,若干项之后,其值会循环出现,所以不必将其所有的项都算出来,只需要算出第一个循环的各个项即可。

5.中国剩余定理(孙子定理):

 

  1. // 递推法实现扩展欧几里德算法  
  2. long exgcd(long a, long b, long *x, long *y)  
  3. {  
  4.     long x0=1, y0=0, x1=0, y1=1;  
  5.     long r, q;  
  6.     *x=0;  
  7.     *y=1;  
  8.   
  9.     r = a % b;  
  10.     q = (a - r) / b;  
  11.     while(r)  
  12.     {  
  13.         *x = x0 - q * x1;  
  14.         *y = y0 - q * y1;  
  15.         x0 = x1;  
  16.         y0 = y1;  
  17.         x1 = *x;  
  18.         y1 = *y;  
  19.   
  20.         a = b;  
  21.         b = r;  
  22.         r = a % b;  
  23.         q = (a - r) / b;  
  24.     }  
  25.     return b;  
  26. }  

 

  1. // 扩展欧几里德算法求逆元  
  2. long minv(long a, long p)  
  3. {  
  4.     long x, y;  
  5.   
  6.     exgcd(a, p, &x, &y);  
  7.   
  8.     return x<0 ? x+p : x;  
  9. }  
  10.   
  11. // 试探法求逆元  
  12. long minv2(long a, long p)  
  13. {  
  14.     long y=1, t;  
  15.     int i;  
  16.   
  17.     if(a < 0) {  
  18.         a = a % p;  
  19.         a += p;  
  20.     }  
  21.   
  22.     for(i=1; i<p; i++) {  
  23.         t = a * i;  
  24.         if(t % p == 1) {  
  25.             y = i;  
  26.             return y;  
  27.         }  
  28.     }  
  29.   
  30.     return y;  
  31. }  
  32.   
  33. int main(void)  
  34. {  
  35.     printf("a=%d m=%d x=%ld x=%ld\n", 65, 83, minv(65, 83), minv2(65, 83));  
  36.     printf("a=%d m=%d x=%ld x=%ld\n", 11663, 103, minv(11663, 103), minv2(11663, 103));  
  37.     printf("a=%d m=%d x=%ld x=%ld\n", 11227, 107, minv(11227, 107), minv2(11227, 107));  
  38.     printf("a=%d m=%d x=%ld x=%ld\n", 11021, 103, minv(11021, 109), minv2(11021, 109));  
  39.   
  40.     // 孙子算经  
  41.     long a[] = {2, 3, 2};  
  42.     long m[] = {3, 5, 7};  
  43.   
  44.     int i, size= sizeof(a)/sizeof(long);  
  45.     long bm=1, subm[size], x=0;  
  46.   
  47.     for(i=0; i<size; i++)  
  48.         bm *= m[i];  
  49.     for(i=0; i<size; i++)  
  50.         subm[i] = bm / m[i];  
  51.     for(i=0; i<size; i++) {  
  52.         x += subm[i] * minv(subm[i], m[i]) * a[i];  
  53.         x %= bm;  
  54.     }  
  55.   
  56.     printf("x=%ld\n", x);  
  57.   
  58.     return 0;  
  59. }  

 

6.同余方程:

 

7.最大公约数,最小公倍数:

http://blog.csdn.net/tigerisland45/article/details/72719362

 

  1. #include <stdio.h>  
  2.   
  3. typedef unsigned long long ULL;  
  4.   
  5. ULL gcd(ULL m, ULL n)  
  6. {  
  7.     return n == 0 ? m : gcd(n, m % n);            //求最小公倍数 欧几里得算法
  8. }  
  9.   
  10. ULL lcm(ULL m, ULL n)  
  11. {  
  12.     return m / gcd(m, n) * n ;  
  13. }  

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值