HDU 4344 大数分解大素数判定

这里贴个模板吧。反正是不太理解

看原题就可以理解用法!!

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;
#define Times 10
typedef __int64 LL;
map<LL,int>m;
LL Random(LL n)
{
    return ((double)rand()/RAND_MAX*n+0.5);
}
LL multi(LL a,LL b,LL mod)
{
    LL ans=0;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=(ans+a)%mod;
        }
        else
        {
            b/=2;
            a=(a+a)%mod;
        }
    }
    return ans;
}
LL Pow(LL a,LL b,LL mod)
{
    LL ans=1;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=multi(ans,a,mod);
        }
        else
        {
            b/=2;
            a=multi(a,a,mod);
        }
    }
    return ans;
}
bool witness(LL a,LL n)
{
    LL d=n-1;
    while(!(d&1))
        d>>=1;
    LL t=Pow(a,d,n);
    while(d!=n-1 && t!=1 && t!=n-1)
    {
        t=multi(t,t,n);
        d<<=1;
    }
    return t==n-1 || d&1;
}
bool miller_rabin(LL n)
{
    if(n==2)
        return true;
    if(n<2||!(n&1))
        return false;
    for(int i=1;i<=Times;i++)
    {
        LL a=Random(n-2)+1;
        if(!witness(a,n))
            return false;
    }
    return true;
}
LL gcd(LL a,LL b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
LL pollard_rho(LL n,LL c)
{
    LL x,y,d,i=1,k=2;
    x=Random(n-1)+1;
    y=x;
    while(1)
    {
        i++;
        x=(multi(x,x,n)+c)%n;
        d=gcd(y-x,n);
        if(1<d&&d<n)
            return d;
        if(y==x)
            return n;
        if(i==k)
        {
            y=x;
            k<<=1;
        }
    }
}
void find(LL n,LL c)
{
    if(n==1)
        return ;
    if(miller_rabin(n))
    {
        m[n]++;
        return ;
    }
    LL p=n;
    while(p>=n)
        p=pollard_rho(p,c--);
    find(p,c);
    find(n/p,c);
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        LL n;
        cin>>n;
        m.clear();
        find(n,2013724);
        if(m.size()==1)
            cout<<1<<" "<<n/m.begin()->first<<endl;
        else
        {
            LL ans=0;
            map<LL,int>::iterator it=m.begin();
            for(;it!=m.end();it++)
                ans+=Pow(it->first,it->second,n);
            cout<<m.size()<<" "<<ans<<endl;
        }
    }
    return 0;
}

  

时间: 2024-10-05 07:15:40

HDU 4344 大数分解大素数判定的相关文章

miller_robin大素数判定

参考了ACdreamer大神的博客http://blog.csdn.net/acdreamers/article/details/7913786 在51nod上看了个10^30范围的素数判定,打表肯定是不行了,应该用miller-robin素数判定加java的BigInteger 首先基于fermat小定理就是gcd(a,p)=1时,a^(p-1)%p=1,所以在生成rand(2,p-1)的随机数后,如果输入的是个素数,那么必有pow(a,p-1)%p=1,这里采用快速幂取模,在一次探查后,若结

HLJOJ1171(大素数判定)

多组测试数据,每组测试数据第一行输入一个正整数n(0< n < 10^9). 每组测试数据,若n为素数,那么输出"YES",否则输出"NO".(引号不输出) 思路:由于n非常的大,打表nlogn也不行,我们换一种思路,我们不打10^9,我们只打出它的开平方10^5就差不多了,找出小于10^5以内的素数,然后我们判定n的时候再用 普通素数判别法判定就行 #include <stdio.h> #include <string.h> #

大素数判定

START 判断一个数是不是素数可以直接暴力或者是素数筛. 但是对于一个特别大的数,直接用素数筛也有可能TLE. 这个时候就要想点别的办法: 1. 筛选法+试除法 首先用素数筛筛出[2,sqrt(n)+1]的素数,然后用这些素数来判断能不能整除n,如果可以,那么n一定是合数,如果都不行,那么n是素数. void olas()//欧拉筛 { int i,j; num=1; memset(u,true,sizeof(u)); for(int i=2;i<=1000000;i++) { if(u[i]

CSU 1552: Friends 图论匹配+超级大素数判定

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 163  Solved: 34[Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestri

HDU 4344 随机法判素数(费马小定理

#include <cstdio> #include <ctime> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; const int N = 108; const int S = 10; ll mult_mod(ll a, ll b, ll c) { a %= c; b %= c; ll ret = 0; while(b) { if(b&am

数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&amp;2429

素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: http://blog.csdn.net/maxichu/article/details/45459533 然后是参考了kuangbin的模板: http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.html 模板如下: //快速乘 (a

数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)

数学渣渣愉快的玩了一把数论,来总结一下几种常用的算法入门,不过鶸也是刚刚入门, 所以也只是粗略的记录下原理,贴下模板,以及入门题目(感受下模板怎么用的) (PS:文中蓝色字体都可以点进去查看百度原文) 附赠数论入门训练专题:点我打开专题(题目顺序基本正常,用以配套数论入门) 一.同余定理 简单粗暴的说就是:若 a-b == m 那么 a%m == b%m 这个模运算性质一眼看出...直接上入门水题: Reduced ID Numbers 附AC代码(这个也没啥模板....知道就好) #inclu

hdu 2012 素数判定 Miller_Rabbin

素数判定 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 71785    Accepted Submission(s): 24969 Problem Description 对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数. Input 输入数据

大数分解,大数判定综合模板

通过poj1811整理这些算法的模板 所有代码如下: 1 #include <iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 #define LL long long 7 const int maxs = 10000000+5; 8 //对于1要外加特判,否则会运行错误 9 //用小素数表做随机种子 10 __int64