一.、快速乘方
此算法解决快速计算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;
}