ACM经典算法之数论

173 篇文章 3 订阅
79 篇文章 0 订阅


转自:http://blog.sina.com.cn/s/blog_93d2ceba010145dr.html


一、(x的二进制长度)


语法:result=BitLength(int x);

参数:

x:

测长的x

返回值:

x的二进制长度

源程序:

 

 

int BitLength(int x)
{
    int 0;
    while (x 0) {
        >>= 1;
        d++;
    }
    return d;
}


二、(返回x的二进制表示中从低到高的第i位)



语法:result=BitAt(int x, int i);

参数:

x:

十进制 x

i:

要求二进制的第i位

返回值:

返回x的二进制表示中从低到高的第i位

注意:

 

 

最低位为第一位

源程序:

 

 

int BitAt(int x, int i)
{
    return (1 << (i-1)) );
}


三、(模取幂运算)


语法:result=Modular_Expoent(int a,int b,int n);

参数:

a、b、n:

a^b mod 的对应参数

返回值:

a^b mod 的值

注意:

 

 

需要BitLength和BitAt

源程序:

 

 

int Modular_Expoent(int a,int b,int n)
{
    int i, y=1;
    for (i BitLength(b); 0; i--)
        
        (y*y)%n;
        if (BitAt(b,i) 0) 
        (y*a)%n;
        }
    return y;
}


四、(求解模线性方程)

语法:result=modular_equation(int a,int b,int n);

参数:

a、b、n:

ax=b (mod n) 的对应参数

返回值:

方程的解

源程序:

 

 

int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by
{
    int t,d;
    if (b==0) {x=1;y=0;return a;}
    d=ext_euclid(b,a %b,x,y);
    t=x;
    x=y;
    y=t-a/b*y;
    return d;
}

void modular_equation(int a,int b,int n)
{
    int e,i,d;
    int x,y;
    d=ext_euclid(a,n,x,y);
    if (b%d>0)
       printf("No answer!\n");
    else
        {
       e=(x*(b/d))%n;
        for (i=0;i<d;i++)
            printf("The %dth answer is %ld\n",i+1,(e+i*(n/d))%n); 
        }
}


五、(求解模线性方程组(中国余数定理))


语法:result=Modular_Expoent(int a,int b,int n);

参数:

B[]、W[]:

a=B[] (mod W[]) 的对应参数

返回值:

的值

注意:

 

 

其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

源程序:

 

 

int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by
{
    int t,d;
    if (b==0) {x=1;y=0;return a;}
    d=ext_euclid(b,a %b,x,y);
    t=x;
    x=y;
    y=t-a/b*y;
    return d;
}


int China(int B[],int W[],int k)
{
   int i;
    int d,x,y,a=0,m,n=1;
    for (i=0;i<k;i++)
        n*=W[i];
    for (i=0;i<k;i++)
       {
       m=n/W[i];
        d=ext_euclid(W[i],m,x,y);
        a=(a+y*m*B[i])%n;
        }
    if (a>0) return a;
    else return(a+n);
}


六、

(筛法素数产生器)

 


语法:result=prime(int a[],int n);

参数:

a[]:

用于返回素数的数组

n:

产生n以内的素数,按升序放入a[]中

返回值:

n以内素数的个数

注意:

 

 

其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

源程序:

 

 

int prime(int a[],int n)
{
    int i,j,k,x,num,*b;
    n++;
    n/=2;
    b=(int *)malloc(sizeof(int)*(n+1)*2);
    a[0]=2;a[1]=3;num=2;
    for(i=1;i<=2*n;i++)
        b[i]=0;
    for(i=3;i<=n;i+=3)
        for(j=0;j<2;j++)
            {
            x=2*(i+j)-1;
            while(b[x]==0)
                {
                a[num++]=x;
                for(k=x;k<=2*n;k+=x)
                    b[k]=1;
                }
            }
    return num;
}


七、(判断一个数是否素数)

语法:result=comp(int n);

参数:

n:

判断n是否素数

返回值:

素数返回1,否则返回0

源程序:

 

 

int comp(int n)
{
   int i,flag=1;
    for (i=2;i<=sqrt(n);i++)
    if (n%i==0) {flag=0;break;}
    if (flag==1) return 1; else return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值