||
求“”的步骤:
再由欧拉定理和消去定理有:
若“a”为质数则,“a”的最小简化剩余系:1、2、3……a-1,共“a-1”个数,即。所以“”的最小简化剩余系只需把“1”到“”中为“a”的倍数的值丢弃即可。若“a”与“b”均为质数,可以直接得出。
欧拉函数值求取c++程序:
int Phi(int n)
{
intYuk[11][2],(*p)[2];
intvalue=n,T=1;
inti,j;
memset(Yuk,0,sizeof(int)*22);
j = 0;
for(i=2;i*i<n;i++)
{
if(!(value%i))
{
while(!(value%i))
{
Yuk[j][0]= i;
Yuk[j][1]= Yuk[j][1]+1;
value/= i;
}
j++;
}
elsecontinue;
}
if(Yuk[0][0]!=0)
{
p = Yuk;
while((*p)[0]!=0)
{
i =p[0][1];
while(--i) T *= p[0][0];
T *=p[0][0] - 1;
p++;
}
}
elseT = n-1;
returnT;
}
//x andy is co-prime. return mod(x^a,y) note:x^2 < 0x7fffffff
int mod_ex_1(int x,int a, int y)
{
int t;
t = 1;
while(a-->0)
{
if((0x7fffffff/t)> x) t *= x;
else
{
t%= y;
t*= x;
}
}
return t%y;
}
// GCD:greatest common divisor. a,b not 0
int GCD(int x, int y)
{
int tmp;
if(x*y==0)return 0;
while(x%y)
{
tmp =x%y;
x = y;
y =tmp;
}
return y;
}
// final,mod(x^a,y)
int mod_ex_2(int x, int a, int y)
{
int j,k,p;
if(x>y) x %= y;
if(!x) return 0;
if(a==1) return x%y;
if(!(y%x)) return x*mod_ex_2(x,a-1,y/x);
k = GCD(x,y);
j = Phi(y/k);
if(k==1) return mod_ex_1(x,a%j,y);
p = mod_ex_1(x/k,a%j,y/k);
return k*((p*mod_ex_2(k,a-1,y/k))%(y/k));
}
最后的程序不算完善,原本期望解决的论坛中看到的,若是上面的程序可以接受的话,这个问题也差不多可以算是解决了。具体程序就不列出了。往后有想法会继续修改这个程序。
mod_ex_1的函数效率不高,可用下面的程序代替。它利用计算机2进制计数的特性,以及幂级数求模过程中反复相乘取模的数值计算过程上的重复,可以把复杂度O(n)减少到O(log(n))。
int mod_ex(int x,int a, int y)
{
inti,j,k;
i = x%y;
for(j=0;(a>>j)>0;j++);
k = 1;
while(j>0)
{
if(a&(1<<--j)) k = (i*k*k)%y;
else k = (k*k)%y;
}
return k;
}
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-12-26 04:40
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社