Pollard-Rho大整数拆分模板

news/2024/7/4 8:54:51

随机拆分,简直机智。

关于过程可以看http://wenku.baidu.com/link?url=JPlP8watmyGVDdjgiLpcytC0lazh4Leg3s53WIx1_Pp_Y6DJTC8QkZZqmiDIxvgFePUzFJ1KF1G5xVVAoUZpxdw9GN-S46eVeiJ6Q-zXdei

看完后,觉得随机生成数然后和n计算gcd,可以将随机的次数根号一下。思想很叼。

对于里面说的birthday trick,在执行次数上我怎么看都只能减一半。只是把平均分布,变成了靠近0的的分布。

不过怎么说,这个好像是大家都公认比较靠谱的。 所以,我就勉强相信了。

/*****************************
大整数拆分模板(long long范围内)
调用Divide(n,222);
返回的结果在divsor中,因子最小值为dmi
注意:复杂度为n^(1/4),多次调用初始化dcnt,dmi
*****************************/

#define INF 1e18

long long divsor[100];
int dcnt=0;
long long dmi=INF;

//输入一个long long 范围内的素数,是素数返回true,否则返回false。定义检测次数TIMES,错误率为(1/4)^TIMES
#define TIMES 10

long long GetRandom(long long n)
{
    //cout<<RAND_MAX<<endl;
    long long num = (((unsigned long long)rand() + 100000007)*rand())%n;
    return num+1;
}

long long Mod_Mul(long long a,long long b,long long mod)
{
    long long msum=0;
    while(b)
    {
        if(b&1) msum = (msum+a)%mod;
        b>>=1;
        a = (a+a)%mod;
    }
    return msum;
}

long long Quk_Mul(long long a,long long b,long long mod)
{
    long long qsum=1;
    while(b)
    {
        if(b&1) qsum=Mod_Mul(qsum,a,mod);
        b>>=1;
        a=Mod_Mul(a,a,mod);
    }
    return qsum;
}

bool Miller_Rabin(long long n)
{
    if(n==2||n==3||n==5||n==7||n==11) return true;
    if(n==1||n%2==0||n%3==0||n%5==0||n%7==0||n%11==0) return false;
    int div2=0;
    long long tn=n-1;
    while( !(tn%2) )
    {
        div2++;
        tn/=2;
    }
    for(int tt=0;tt<TIMES;tt++)
    {
        long long x=GetRandom(n-1); //随机得到[1,n-1]
        if(x==1) continue;
        x=Quk_Mul(x,tn,n);
        long long pre=x;
        for(int j=0;j<div2;j++)
        {
            x = Mod_Mul(x, x, n);
            if(x==1&&pre!=1&&pre!=n-1) return false;
            pre=x;
        }
        if(x!=1) return false;
    }
    return true;
}

long long gcd(long long a,long long b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}

long long pollard_rho(long long dn,long long dc)
{
    long long x,y,d,i=1,k=2;
    x = GetRandom(dn-1);
    y = x;
    while(1)
    {
        i++;
        x = (Mod_Mul(x, x, dn) + dc)%dn;
        d = gcd( y-x , dn );
        if(1 < d && d < dn )
            return d;
        if( y==x ) return dn;
        if( i==k )
        {
            y=x;
            k <<= 1;
        }
    }
}


void Divide(long long dn,int dk)
{
    if(dn==1) return ;
    if( Miller_Rabin(dn) == true )
    {
        divsor[dcnt++]=dn;
        dmi = min(dmi,dn);
        return ;
    }
    long long dtmp=dn;
    while(dtmp>=dn) dtmp = pollard_rho(dtmp,dk--);//随机寻找dn的因子,dtmp
    Divide(dtmp, dk);
    Divide(dn/dtmp,dk);
}

/*
int main() {
    int T;
    cin>>T;
    while(T--)
    {
        long long n;
        cin>>n;
        if( Miller_Rabin(n) ) printf("Prime\n");
        else
        {
            dmi=INF;
            dcnt=0;
            Divide(n,222);
            cout<<dmi<<endl;
        }
    }
    return 0;
}
*/

 

转载于:https://www.cnblogs.com/chenhuan001/p/5017762.html


http://www.niftyadmin.cn/n/3069164.html

相关文章

带头单链表的增删改查

用带头的单链表来实现——水浒英雄排行榜的增删改查操作 代码块如下 public class singleLinkedListDemo {public static void main(String[] args) {HeroNode hero01 new HeroNode(1, "宋江", "及时雨");HeroNode hero02 new HeroNode(2, "卢俊义…

项目实施

项目实施前应准备的材料&#xff1a; 1&#xff1a;根据项目经理提供的设备清单&#xff0c;确定项目现场有哪些设备&#xff0c;服务器及终端盒子的数量&#xff0c;矩阵&#xff0c;编码器等设备是否必须。 2&#xff1a;查看系统图&#xff0c;看各个设备的链路及信号是否与…

用数组模拟队列

思路导图 代码块如下 public class ArrayQueueDemo {public static void main(String[] args) {//先新建一个ArrayQueue类ArrayQueue queue new ArrayQueue(3);Scanner scanner new Scanner(System.in);char key ;//key用来接收用户从键盘输入要添加的数字boolean looptru…

使用Struts 2框架实现文件下载

从服务器发送一个文件到浏览器需要以下几个步骤 把HTTP响应里的ContentType标头设置为被下载文件的内容类型。ContentType标头的作用是表明数据包里的数据是什么类型&#xff0c; 它由一个多媒体类型和一个子类型标识符组成&#xff08;可以去http://www.iana.org/assignments/…

实验一安卓开发微信页面设计

实验一安卓开发微信页面设计 功能要求&#xff1a; 1.页面具有标题 2.具有四个页面&#xff0c;页面具有底部选择框&#xff0c;同时具有选择事件&#xff0c;当点击选择事件的时候进行页面切换 3.页面内容不超出边界且清晰 思路分析&#xff1a; 该微信界面由三部分组成 1页面…

实验二: 安卓应用UI设计

实验目标和实验内容&#xff1a; 1、掌握UI设计中的layout布局&#xff08;约束布局&#xff09;与基本控件&#xff08;button、text、imageview等&#xff09;&#xff1b; 2、掌握复杂控件与adapter的使用 实验结果&#xff1a;&#xff08;实验小结与结果截图&#xff09…

使用C++名单在文档处理和学生成绩管理系统相结合

对于学生成绩管理系统&#xff0c;我并不陌生&#xff0c;几乎学习C人的语言。做项目会想到学生成绩管理系统&#xff0c;我也不例外。在研究中的一段时间C语言之后&#xff0c;还用C语言到学生管理系统&#xff0c;然后做几个链接。计数&#xff0c;这个系统是以前的系统上的改…

实验三: 服务与广播

实验目标和实验内容&#xff1a; 1、掌握服务的基本概念&#xff0c;能编写服务过程并进行调用&#xff1b; 2、掌握广播的基本概念&#xff0c;能实现广播通信。 3、需实现的具体功能为&#xff1a; 短信到来时自动产生的系统广播→激活音乐播放服务程序→活动组件程序使得停止…