moset的个人博客分享 http://blog.sciencenet.cn/u/moset 以心为绢,绘山河;以思为海,汇百流;以文为宴,会高朋。

博文

(y^a)(mod k)的程序

已有 4240 次阅读 2014-5-15 12:05 |系统分类:科研笔记| 求余


求“”的步骤: 




再由欧拉定理和消去定理有:      


 




若“a”为质数则,“a”的最小简化剩余系:123……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;

}




https://blog.sciencenet.cn/blog-567861-794662.html

上一篇:排列组合的几个程序
收藏 IP: 218.24.71.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-12-26 04:40

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部