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的一个素因子
初始化:
重复执行如下操作:
直到 是完全平方数.
初始化:
注意,此时的i是上一个循环终止时的i值
重复执行如下操作:
直到
T如果 !=
||
!=
, 此时
就是
的一个素因子. 否则通过改变
的值的大小来做这些操作.
注意,在这儿的 中的Pi是最后
相等时的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++;
}