数论小模版解题报告
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)在上一步是能够算出来的。
快速乘方算法其实是一个二分思想,如果对这个还是不太了了解就具体看程序。
二、 素数筛选
素数也叫质数,即只能被1和自己整除的数。在程序中,怎么筛选出在一定范围中的素数看?我们这样做:
1)、先从2开始找,然后删去这一范围中所有能被2整数的数。
2)、找到下一个没有被删除的数字n。
3)、删去这一范围中所有能整除n的数。
4)、如果n*n>“范围最大值”就跳出,否则跳到第二步。
另一个:
三、求最大公约数
先看B是否能整除A,如果能整除,直接输出B;如果不能整除,让新A等于原来的B,新B等于原来的A模上原来的B,此时再看B是否能整除A,重复上面步骤即可。
四、模幂运算
数论中计算中经常出现的一种运算就是求一个整数的幂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
算法如下:
(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 ...
算法如下:
此算法解决快速计算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; }
相关文章推荐
- HDU 1796 How many integers can you find 解题报告(数论)
- POJ 1001 解题报告 高精度大整数乘法模版
- 解题报告:N.密码破解 (数论 含推导) “盛大游戏杯”第15届上海大学程序设计联赛夏季赛
- 数论基础练习赛-解题报告
- [数论]中南大学 2013 校赛 G 题解题报告
- BZOJ 2118 数论+最短路(SPFA) 解题报告
- HDU 1018 Big Number数论(解题报告)
- poj2635The Embarrassed Cryptographer(数论)(解题报告)
- 解题报告:HDU_3944 DP? 数论
- A.yuna学数论(解题报告)
- codeforces 158D 解题报告 数论+暴力
- 解题报告:HDU4549 M斐波那契数列 数论三大基础(快速幂+矩阵快速幂+费马小定理)
- 【数论】MMT数解题报告
- 数论基础训练(2)-解题报告
- 【ACM训练计划】 数论、组合数学 好题精选+解题报告
- [解题报告]最强DE战斗力-第五届程序设计大赛(数论)
- BZOJ 2005 [Noi 2010] 数论 解题报告
- POJ-1730 Perfect Pth Powers 解题报告(数论) 最大开方数
- OPJ-1067 取石子游戏 解题报告(数论) 取石子游戏,betty定理
- BZOJ 2463 数论(欧拉函数) 解题报告