您的位置:首页 > 其它

数论小模版解题报告

2012-08-21 09:07 239 查看
一.、快速乘方

此算法解决快速计算Ak这类问题,步骤如下:

1)将k写成二进制数s,s[1]为最低位。

2)假设之前i-1位求出的得数为Ans,如果s[i]位上的数字为1,那么现在的答案就是Ans*A^2^i而A^(i-1)在上一步是能够算出来的。

快速乘方算法其实是一个二分思想,如果对这个还是不太了了解就具体看程序。

int QKpower(int a,int k)
{
int ans=1,temp=a;
while(k)
{
if(k%2)
ans=ans*temp;
temp=temp*temp;
k/=2;
}
return ans;
}


二、 素数筛选

素数也叫质数,即只能被1和自己整除的数。在程序中,怎么筛选出在一定范围中的素数看?我们这样做:

1)、先从2开始找,然后删去这一范围中所有能被2整数的数。

2)、找到下一个没有被删除的数字n。

3)、删去这一范围中所有能整除n的数。

4)、如果n*n>“范围最大值”就跳出,否则跳到第二步。

int prime[500000];
void choseprime(int n)
{
prime[1]=prime[0]=1;
for(int i=2;i*i<=n;i++)
if(prime[i]==0)
for(int j=2*i;j<=n;j+=i)
prime[j]=1;
}

另一个:

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int M=1000000;
bool is[M];//判断是否为素数
int prime[M];
int getprime(int n)
{
int i,j,k=0;
int s,e=(int)(sqrt(0.0+n)+1);
memset(is,false,sizeof(is));
prime[k++]=2;
is[0]=is[1]=0;
for(i=4;i<=n;i+=2) is[i]=true;
for(i=3;i<e;i+=2) if(!is[i]){
prime[k++]=i;
for(s=i*2,j=i*i;j<n;j+=s)
is[j]=true;
}
for(;i<n;i+=2) if(!is[i]) prime[k++]=i;
return k;//n之内的素数个数
}
int main()
{
int n,i;
cin>>n;
cout<<getprime(n)<<endl;
for(i=2;i<=n;i++)
if(!is[i]) cout<<i<<" ";
system("pause");
return 0;
}


三、求最大公约数

先看B是否能整除A,如果能整除,直接输出B;如果不能整除,让新A等于原来的B,新B等于原来的A模上原来的B,此时再看B是否能整除A,重复上面步骤即可。

int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}


四、模幂运算

数论中计算中经常出现的一种运算就是求一个整数的幂a^r对另一个数m的模幂运算,既指a^r mod m

(1)、模幂运算1-累次计算法

d=a^r mod m =(…(((((a mod m) * a ) mod m) * a) mod m)
… * a) mod m

算法如下:

long modular_power1(long a,long r,long m)
{
long d=1,i;
a=a%m;
for(i=0;i<r;i++)
d=(a*d)%m;
return d;
}


(2)、模幂运算2-快速运算法

将r转化成二进制的形式,,然后a反复平方取余。然后将最低位开始,自右至左逐位扫描。每次迭代时,用到下面两个恒等式:

a^2c mod m = (a^2)^c mod m

a^2c+1 mod m =a * (a^2)^c mod m

需计算:a mod m , a^2 mod m , (a^2)^2 mod m ...

算法如下:

long modular_power2(long a,long r,long m)
{
long d=1,t=a;
while(r>0)
{
if((r%2)==1) d=(d*t)%m;
r=r/2;
t=t*t%m;
}
return d;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: