【BZOJ-3667】Rabin_Miller算法 随机化判素数

3667: Rabin-Miller算法

Time Limit: 60 Sec  Memory Limit: 512 MB
Submit: 983  Solved: 302
[Submit][Status][Discuss]

Description

Input

第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数。你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 
第二,如果不是质数,输出它最大的质因子是哪个。

Output

第一行CAS(CAS<=350,代表测试数据的组数) 
以下CAS行:每行一个数字,保证是在64位长整形范围内的正数。 
对于每组测试数据:输出Prime,代表它是质数,或者输出它最大的质因子,代表它是和数

Sample Input

6
2
13
134
8897
1234567654321
1000000000000

Sample Output

Prime
Prime
67
41
4649
5

HINT

数据范围: 
保证cas<=350,保证所有数字均在64位长整形范围内。

Source

Solution

我以为啊,这个Discuss很好

裸题,卡常..自己原来的板子被卡死了..于是换成网上的新版...

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
long long read()
{
    long long x=0,f=1; char ch=getchar();
    while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();}
    while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
long long X,maxz;
long long gcd(long long a,long long b)
{
    if (b==0) return a;
    return gcd(b,a%b);
}
//long long mul(long long a,long long b,long long p)
//{
//    if (b==0) return 0; if (b==1) return a%p;
//    long long re;
//    re=mul(a,b>>1,p);
//    if ((b&1)==1) return (re+re+a)%p;
//             else return (re+re)%p;
//}
long long mul(long long a,long long b,long long p)
{
    long long tmp=(a*b-(long long)((long double)a/p*b+1e-8)*p);
    return tmp<0?tmp+p:tmp;
}
long long quick_pow(long long a,long long b,long long p)
{
    long long ans=1; a%=p;
    for (long long i=b; i; i>>=1,a=mul(a,a,p))
        if (i&1) ans=mul(ans,a,p);
    return ans;
}
bool check(long long a,long long n,long long r,long long s)
{
    long long ans=quick_pow(a,r,n),p=ans;
    for(int i=1; i<=s; i++)
    {
        ans=mul(ans,ans,n);
        if(ans==1&&p!=1&&p!=n-1)return 1;
        p=ans;
    }
    if(ans!=1)return 1;else return 0;
}
bool Robin_Miller(long long x)
{
    if(x<=1) return 0;
    if(x==2) return 1;
    if(x%2==0) return 0;
    long long r=x-1,s=0;
    while(r%2==0) r/=2,s++;
    for(int i=0; i<20; i++)
        if(check(rand()%(x-1)+1,x,r,s))
            return 0;
    return 1;
}
long long Rho(long long x,long long t)
{
    long long k=2,a=rand()%x,b=a,p=1;
    for(long long i=1; p==1; i++)
    {
        a=(mul(a,a,x)+t)%x;
        p=b>a?b-a:a-b;
        p=gcd(x,p);
        if(i==k) b=a,k+=k;
    }
    return p;
}
void work(long long x)
{
    if(x==1) return;
    if(Robin_Miller(x)){maxz=max(x,maxz);return;}
    long long t=x;
    while(t==x) t=Rho(x,rand()%(x-1)+1);
    work(t); work(x/t);
}
int main()
{
    int n;n=read();
    while (n--)
        {
            X=read(); maxz=0;
            work(X);
            if (maxz==X) puts("Prime");
                else printf("%lld\n",maxz);
        }
    return 0;
}

论常数的差距....:So SAD.

时间: 2024-11-13 05:03:51

【BZOJ-3667】Rabin_Miller算法 随机化判素数的相关文章

BZOJ.3667.Rabin-Miller算法(MillerRabin PollardRho)

题目链接 Pollard_Rho:http://blog.csdn.net/thy_asdf/article/details/51347390 #include<cstdio> #include<cctype> #include<algorithm> #define gc() getchar() const int p[]={2,3,5,7,11,13,17,19}; typedef long long LL; LL Ans; inline LL read() { LL

Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][Status][Discuss] Description Input 第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 第二,如果不是质数,输出它最大的质因子是哪个. O

【Miller-Rabin随机判素数算法】

实用性介绍:████████████████████████████████ 科学性证明:████████████████████████████████ ·在运算中尝试使用quick-pow和quick-mul加速.但实际告诉我们,在多次判素数的情况下,使用quick-mul反而会减速,原因可能是原装%运算消耗了大量时间.(复判重复数T取在4以上,不然很危险) ·大米饼目前只能将它作为"黑盒代码". 1 #include<bits/stdc++.h> 2 #define

Miller-rabin判素数

用Miller-rabin判素数之前,先要知道一个叫费马小定理的东西. 费马小定理:如果p是质数,那么任意和p互质的数的p-1次方对p取模都等于一. 即:任意gcd(a,p)==1,那么a^(p-1)≡1(mod p) 既然我们用费马小定理又得到了一个新的质数的性质,那么我们就可以用这个性质来判定素数. 为了判定p是不是质数,我们随机检验一些a检验a^(p-1)mod p是否为1 但是这样判定一个素数并不是百分百正确的,有一些数不是素数,但依据费马小定理还是会判定成素数. 例如:p=561=3*

bzoj 3667

3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1214  Solved: 368[Submit][Status][Discuss] Description Input 第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 第二,如果不是质数,输出它最大的质因子是哪个. Output

HDU 2138 How many prime numbers (判素数,米勒拉宾算法)

题意:给定一个数,判断是不是素数. 析:由于数太多,并且太大了,所以以前的方法都不适合,要用米勒拉宾算法. 代码如下: #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #include <map> #include <cctype> u

Miller-Rabin算法 codevs 1702 素数判定 2

转载自:http://www.dxmtb.com/blog/miller-rabbin/ 普通的素数测试我们有O(√ n)的试除算法.事实上,我们有O(slog³n)的算法. 定理一:假如p是质数,且(a,p)=1,那么a^(p-1)≡1(mod p).即假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1.(费马小定理) 该定理的逆命题是不一定成立的,但是令人可喜的是大多数情况是成立的. 于是我们就得到了一个定理的直接应用,对于待验证的数p,我们不断取a∈[1,p-1]且a∈

数组拷贝、数组函数、通过数组函数来模拟数据结构的栈和队列、回调的意义、数组函数的排序问题、算法以及寻找素数的筛选法

1.数组的拷贝数组拷贝时指针的指向问题. 数组在拷贝时,指针的位置随之复制[这一点拷贝是完全一样]但是如果拷贝的数组的指针是非法的,那么拷贝出新指针的位置进行初始化<?php$arr1=array('123');end($arr1);next($arr1);//这个指针非法$arr2 = $arr1;//这里进行数组的拷贝var_dump(current($arr2));//得到指向‘123’元素的指针var_dump(current($arr1));//此时这个数组的指针有问题?> 但是拷贝

重复造轮子之RSA算法(一) 大素数生成

出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int bitLength, Random rnd) { bitLength是期望生成的素数的二进制位数, rnd是随机数发生器 函数注释表明, 这个方法的返回值为合数的概率为2^-100 生成100个1024位的素数, 耗时13471ms 但是显然我不打算直接使用这个函数, 要做就从最底层做起! 目前的做