hdu 2138 How many prime numbers(Fermat素数判定)

费马(Fermat)测试:重复t次。如果每次得到n可能为素数,则n为素数的概率为1-(1/2t)。

 

//31MS

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef long long LL;

LL mod_exp(LL a, LL n, LL m) // a^n(mod m)
{
    LL sum = 1;
    while(n>0)
    {
        if(n&1) sum = sum * a % m;
        a = a * a % m;
        n >>= 1;
    }
    return sum;
}

bool Fermat(LL n, int tnum = 10)
{
    if(n == 2) return true;
    if( n % 2 == 0 ) return false;
    while(tnum--)
    {
        //rand() * X / RAND_MAX + Y; 产生[Y,X+Y]内的随机数
        //    LL b = rand() * (n-2) /RAND_MAX + 1;
        LL b = rand() * (n-3) /RAND_MAX + 2;
        if( mod_exp(b, n-1, n) != 1 ) return false;
    }
    return true;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("tdata.txt","r",stdin);
#endif
    srand( (unsigned)time(0) );
    int n,cnt;
    LL a;
    while(scanf("%d",&n)!=EOF)
    {
        cnt=0;
        while(n--)
        {
            scanf("%I64d",&a);
            if(Fermat(a)) cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

//****************************************************************************************
15MS,网上抄的,并不那么准确,数据弱而已:

#include <stdio.h>

typedef long long LL;

LL mod_exp(LL a, LL n, LL m) // a^n(mod m)
{
    LL sum = 1;
    while(n>0)
    {
        if(n&1) sum = sum * a % m;
        a = a * a % m;
        n >>= 1;
    }
    return sum;
}

int tb[]= {2,7,61};
bool Fermat(LL n)
{
    if(n == 2) return true;
    if( n % 2 == 0 ) return false;
    for(int i=0; i<3; i++)
        if( mod_exp(tb[i], n-1, n) != 1 ) return false;
    return true;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("tdata.txt","r",stdin);
#endif
    int n,cnt;
    LL a;
    while(scanf("%d",&n)!=EOF)
    {
        cnt=0;
        while(n--)
        {
            scanf("%I64d",&a);
            if(Fermat(a)) cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

posted @ 2010-09-11 09:34  菜到不得鸟  阅读(454)  评论(0)    收藏  举报