SQUFOF算法

SQUFOF算法:
参考:维基百科 http://en.wikipedia.org/wiki/SQUFOF#Algorithm

思路:寻找一对整数x和y使其满足x^2=y^2(mod n),此时计算gcd(x-y,n)就会得到n的一个素因子,此时素因子在x和y之间

输入:输入一个n和k,要求n既不是完全平方数也不是素数,k是一个乘数
输出:n的一个素因子


初始化:P_0=\lfloor\sqrt{kN}\rfloor,Q_0=1,Q_1=kN-P_0^2.

重复执行如下操作:

b_i=\left\lfloor\frac{\lfloor\sqrt{kN}\rfloor+P_{i-1}}{Q_i}\right\rfloor,P_i=b_iQ_i-P_{i-1},Q_{i+1}=Q_{i-1}+b_i(P_{i-1}-P_i)

直到 Q_i 是完全平方数.

初始化:b_0=\left\lfloor\frac{\lfloor\sqrt{kN}\rfloor-P_{i-1}}{\sqrt{Q_i}}\right\rfloor,P_0=b_0\sqrt{Q_i}+P_{i-1},Q_0=\sqrt{Q_i},Q_1=\frac{kN-P_0^2}{Q_0}

注意,此时的i是上一个循环终止时的i值

重复执行如下操作:

b_i=\left\lfloor\frac{\lfloor\sqrt{kN}\rfloor+P_{i-1}}{Q_i}\right\rfloor,P_i=b_iQ_i-P_{i-1},Q_{i+1}=Q_{i-1}+b_i(P_{i-1}-P_i)

直到 P_{i+1}=P_i.

T如果 f=\gcd(N,P_i)  !=1 ||f=\gcd(N,P_i) !=N, 此时 f就是 N的一个素因子. 否则通过改变 k的值的大小来做这些操作.

注意,在这儿的f=\gcd(N,P_i) 中的Pi是最后P_{i+1}=P_i.相等时的Pi

一个例子

N = 11111, k = 1

P0 = 105 Q0 = 1 Q1 = 86

P1 = 67 Q1 = 86 Q2 = 77

P2 = 87 Q2 = 77 Q3 = 46

P3 = 97 Q3 = 46 Q4 = 37

P4 = 88 Q4 = 37 Q5 = 91

P5 = 94 Q5 = 91 Q6 = 25

Here Q6 is a perfect square

P0 = 104 Q0 = 5 Q1 = 59

P1 = 73 Q1 = 59 Q2 = 98

P2 = 25 Q2 = 98 Q3 = 107

P3 = 82 Q3 = 107 Q4 = 41

P4 = 82

Here P3 = P4

gcd(11111, 82) = 41, which is a factor of 11111.


const int maxn=100;

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

long long b[maxn],p[maxn],q[maxn];
long long SQUFOF(long long n,long long k)
{
    long long a=(long long )(sqrt(k*n*1.0));
    long long t;
    int i;
    k=1;
    p[0]=a;
    q[0]=1;
    q[1]=k*n-p[0]*p[0];
    for(i=1;i<maxn;i++)
    {
        b[i]=(long long)((a+p[i-1])/q[i]);
        p[i]=b[i]*q[i]-p[i-1];
        q[i+1]=q[i-1]+b[i]*(p[i-1]-p[i]);
        t=(long long)sqrt(q[i]*1.0);
        if(t*t==q[i])break;
    }
    b[0]=(long long)((a-p[i-1])/t);
    p[0]=b[0]*t+p[i-1];
    q[0]=t;
    q[1]=(k*n-p[0]*p[0])/q[0];
    for(i=1;i<maxn;i++)
    {
        b[i]=(long long)((a+p[i-1])/q[i]);
        p[i]=b[i]*q[i]-p[i-1];
        q[i+1]=q[i-1]+b[i]*(p[i-1]-p[i]);
        if(p[i+1]==p[i])break;
    }
    long long f=gcd(n,p[i]);
    if(f!=1||f!=n)return f;
    else k++;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值