zoukankan      html  css  js  c++  java
  • 51nod1186(Miller-Rabin)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1186

    题意:中文题目诶~

    思路:miller_rabin模板 (详情可参见: http://blog.csdn.net/s031302306/article/details/51606018)

    注意这里的 n 为 1e30,需要用字符串处理

    代码:

      1 #include <string.h>
      2 #include <cstdlib>
      3 
      4 #define MAXL 4
      5 #define M10 1000000000
      6 #define Z10 9
      7 
      8 const int zero[MAXL - 1] = {0};
      9 
     10 struct bnum{
     11     int data[MAXL]; //  断成每截9个长度
     12     //  读取字符串并转存
     13     void read(){
     14         memset(data, 0, sizeof(data));
     15         char buf[32];
     16         scanf("%s", buf);
     17         int len = (int)strlen(buf);
     18         int i = 0, k;
     19         while (len >= Z10){
     20             for (k = len - Z10; k < len; ++k){
     21                 data[i] = data[i] * 10 + buf[k] - '0';
     22             }
     23             ++i;
     24             len -= Z10;
     25         }
     26         if (len > 0){
     27             for (k = 0; k < len; ++k){
     28                 data[i] = data[i] * 10 + buf[k] - '0';
     29             }
     30         }
     31     }
     32 
     33     bool operator == (const bnum &x){
     34         return memcmp(data, x.data, sizeof(data)) == 0;
     35     }
     36 
     37     bnum & operator = (const int x){
     38         memset(data, 0, sizeof(data));
     39         data[0] = x;
     40         return *this;
     41     }
     42 
     43     bnum operator + (const bnum &x){
     44         int i, carry = 0;
     45         bnum ans;
     46         for (i = 0; i < MAXL; ++i){
     47             ans.data[i] = data[i] + x.data[i] + carry;
     48             carry = ans.data[i] / M10;
     49             ans.data[i] %= M10;
     50         }
     51         return  ans;
     52     }
     53 
     54     bnum operator - (const bnum &x){
     55         int i, carry = 0;
     56         bnum ans;
     57         for (i = 0; i < MAXL; ++i){
     58             ans.data[i] = data[i] - x.data[i] - carry;
     59             if (ans.data[i] < 0){
     60                 ans.data[i] += M10;
     61                 carry = 1;
     62             }else{
     63                 carry = 0;
     64             }
     65         }
     66         return ans;
     67     }
     68 
     69     //  assume *this < x * 2
     70     bnum operator % (const bnum &x){
     71         int i;
     72         for (i = MAXL - 1; i >= 0; --i){
     73             if (data[i] < x.data[i]){
     74                 return *this;
     75             }
     76             else if (data[i] > x.data[i]){
     77                 break;
     78             }
     79         }
     80         return ((*this) - x);
     81     }
     82 
     83     bnum & div2(){
     84         int  i, carry = 0, tmp;
     85         for (i = MAXL - 1; i >= 0; --i){
     86             tmp = data[i] & 1;
     87             data[i] = (data[i] + carry) >> 1;
     88             carry = tmp * M10;
     89         }
     90         return *this;
     91     }
     92 
     93     bool is_odd(){
     94         return (data[0] & 1) == 1;
     95     }
     96 
     97     bool is_zero(){
     98         for (int i = 0; i < MAXL; ++i){
     99             if (data[i]){
    100                 return false;
    101             }
    102         }
    103         return true;
    104     }
    105 };
    106 
    107 void mulmod(bnum &a0, bnum &b0, bnum &p, bnum &ans){//计算a0*b0%p
    108     ans = 0;
    109     bnum tmp = a0, b = b0;
    110     while (!b.is_zero()){
    111         if (b.is_odd()){
    112             ans = (ans + tmp) % p;
    113         }
    114         tmp = (tmp + tmp) % p;
    115         b.div2();
    116     }
    117 }
    118 
    119 void powmod(bnum &a0, bnum &b0, bnum &p, bnum &ans){//计算a0^b0%p
    120     bnum tmp = a0, b = b0;
    121     ans = 1;
    122     while (!b.is_zero()){
    123         if (b.is_odd()){
    124             mulmod(ans, tmp, p, ans);
    125         }
    126         mulmod(tmp, tmp, p, tmp);
    127         b.div2();
    128     }
    129 }
    130 
    131 bool MillerRabinTest(bnum &p, int iter){
    132     int i, small = 0, j, d = 0;
    133     for (i = 1; i < MAXL; ++i){
    134         if (p.data[i]){
    135             break;
    136         }
    137     }
    138     if (i == MAXL){
    139         // small integer test
    140         if (p.data[0] < 2){
    141             return  false;
    142         }
    143         if (p.data[0] == 2){
    144             return  true;
    145         }
    146         small = 1;
    147     }
    148     if (!p.is_odd()){
    149         return false;   //  even number
    150     }
    151     bnum a, s, m, one, pd1;
    152     one = 1;
    153     s = pd1 = p - one;
    154     while (!s.is_odd()){
    155         s.div2();
    156         ++d;
    157     }
    158 
    159     for (i = 0; i < iter; ++i){
    160         a = rand();
    161         if (small){
    162             a.data[0] = a.data[0] % (p.data[0] - 1) + 1;
    163         }else{
    164             a.data[1] = a.data[0] / M10;
    165             a.data[0] %= M10;
    166         }
    167         if (a == one){
    168             continue;
    169         }
    170 
    171         powmod(a, s, p, m);
    172 
    173         for (j = 0; j < d && !(m == one) && !(m == pd1); ++j){
    174             mulmod(m, m, p, m);
    175         }
    176         if (!(m == pd1) && j > 0){
    177             return false;
    178         }
    179     }
    180     return true;
    181 }
    182 
    183 int main(void){
    184     bnum x;
    185     x.read();
    186     puts(MillerRabinTest(x, 5) ? "Yes" : "No");
    187     return 0;
    188 }
    View Code

    对于long long范围:

     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #define ll long long
     5 using namespace std;
     6 
     7 //利用二进制计算a*b%mod
     8 ll multi_mod(ll a, ll b, ll mod){
     9     ll ans = 0LL;
    10     a %= mod;
    11     while(b){
    12         if (b & 1LL) ans = (ans+a)%mod;
    13         b >>= 1LL;
    14         a = (a+a)%mod;
    15     }
    16     return ans;
    17 }
    18 
    19 //计算a^b%mod
    20 ll power_mod(ll a, ll b, ll mod){
    21     ll ans = 1LL;
    22     a %= mod;
    23     while(b){
    24         if(b & 1LL) ans = multi_mod(ans, a, mod);
    25         b >>= 1LL;
    26         a = multi_mod(a, a, mod);
    27     }
    28     return ans;
    29 }
    30 
    31 //Miller-Rabin测试,测试n是否为素数
    32 bool miller_rabin(ll n, int repeat){
    33     if (2LL == n || 3LL == n) return true;
    34     if (n%2==0 || n%3==0 || n%5==0) return false;
    35 
    36     //将n分解为2^s*d
    37     ll d = n - 1LL;
    38     int s = 0;
    39     while(!(d & 1LL)){
    40         s++;
    41         d >>= 1LL;
    42     }
    43     // srand((unsigned)time(0));
    44     for(int i=0; i<repeat; ++i){//重复repeat次
    45         ll a = rand() % (n - 3) + 2;//取一个随机数,[2,n-1)
    46         ll x = power_mod(a, d, n);
    47         ll y = 0LL;
    48         for(int j=0; j<s; ++j){
    49             y = multi_mod(x, x, n);
    50             if (1LL == y && 1LL != x && n-1LL != x) return false;
    51             x = y;
    52         }
    53         if (1LL != y) return false;
    54     }
    55     return true;
    56 }
    57 
    58 int main(void){
    59     ll n;
    60     cin >> n;
    61     if(miller_rabin(n, 5)) cout << "Yes" << endl;
    62     else cout << "No" << endl;
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    php的下载与安装
    apache 的下载与配置
    Composer 安装与使用
    WampServer 的安装
    SQLServer主键约束和唯一约束的区别
    Mac如何修改Host
    解决XCode11中 [Application] The app delegate must implement the window property if it wants to use a main storyboard file.的问题
    Xcode10.1 import头文件无法索引
    iOS
    如何让windows服务器IIS支持.apk/.ipa文件下载
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6904418.html
Copyright © 2011-2022 走看看