• bzoj 3667


    3667: Rabin-Miller算法

    Time Limit: 60 Sec  Memory Limit: 512 MB
    Submit: 1214  Solved: 368
    [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位长整形范围内。 

     裸的rho。跑得好慢,30多秒,是不是我乘法那一块比别人慢啊?

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #define rep(i,j,k) for(register int i = j; i <= k; i++)
    #define dow(i,j,k) for(register int i = j; i >= k; i--)
    #define ll long long
    using namespace std;
     
    inline ll read() {
        ll s = 0, t = 1; char c = getchar();
        while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
        while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
        return s * t; 
    }
     
    const int times = 15;
    inline void M(ll &x,ll p) { if( x >= p ) x -= p; }
    inline void Max(ll &x,ll v) { if( v > x ) x = v; }
    inline ll mul(ll x,ll t,ll p) {
        ll ret = 0;
        while( t ) {
            if( t & 1 ) M(ret += x,p);
            M(x += x,p), t >>= 1; 
        } return ret;
    }
    inline ll pow(ll x,ll t,ll p) {
        ll ret = 1;
        while( t ) {
            if( t & 1 ) ret = mul(ret,x,p);
            x = mul(x,x,p), t >>= 1;
        } return ret;
    }
    inline bool miller_rabin(ll n) {
        if( n == 2 || n == 3 || n == 5 ) return 1;
        if( n < 2 || !(n&1) || n % 3 == 0 || n % 5 == 0 ) return 0;
        ll m = n - 1; int k = 0;
        while( !(m & 1) ) m >>= 1, k++;
        rep(i,1,times) {
            ll x = pow(rand() % (n-1) + 1,m,n), y;
            rep(j,1,k) {
                y = mul(x,x,n);
                if( y == 1 && x != 1 && x != n - 1 ) return 0;
                x = y; 
            }
            if( y != 1 ) return 0;
        }
        return 1;
    }
     
    inline ll gcd(ll x,ll y) {
        ll t;
        while( y ) t = x, x = y, y = t % y;
        return x;
    }
    inline ll rho(ll n,int c) {
        ll i = 1, k = 2, x = rand() % (n-1) + 1, y = x;
        while( 1 ) {
            i++;
            x = (mul(x,x,n) + c) % n;
            ll d = gcd((y-x+n)%n,n);
            if( 1 < d && d < n ) return d;
            if( x == y ) return n;
            if( i == k ) y = x, k <<= 1;
        }
    }
     
    ll ans = 0;
    inline void find(ll x,int k) {
        if( x == 1 || x <= ans ) return;
        if( miller_rabin(x) ) { Max(ans,x); return; }
        ll p = x; int c = k;
        while( p >= x ) p = rho(x,k--);
        find(p,c), find(x/p,c);
    } 
     
    int main() {
        int T = read();
        while( T-- ) {
            ll n = read(); ans = 0;
            find(n,120);
            if( ans == n ) puts("Prime");
            else printf("%lld
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:

    如何找回自己!
    身体锻炼靶心心率!
    圣人言大任之人!
    如何修清净心?(净空老法师法语)
    vim 查询定位!
    深切悼念灾区遇难同胞!
    求后倒零
    植物大战僵尸【二分答案, 加贪心思想】
    植物大战僵尸【二分答案, 加贪心思想】
  • 原文地址:https://www.cnblogs.com/83131yyl/p/6182822.html
Copyright © 2020-2023  润新知