基础篇——数论基础
来源:互联网 发布:头戴式蓝牙推荐 知乎 编辑:程序博客网 时间:2024/06/07 01:37
数论基础主要有三点。1.最大公约数。2.素数问题。3.快速幂取模。
一:最大公约数
正常的思路,求最大公约数都是从2开始到n-1求最大能整除的数即为最大公约数。但这样算的时间为o(n),相当耗时。故在求最大公约数时,提出了辗转相除法。
现有a,b两个数,a除以b的商和余数分别是p和q,所以a=b*p+q,所以gcd( b , q )整除a,b故而整除gcd( a ,b )。反之因为q=a-b*q,可得gcd( a,b )整除gcd( b,q )。因此gcd( a,b )=gcd( b,a%b )。由于gcd的第二个参数是不断减小的,最终会得到gcd( a,b )=gcd( c,0 )。0和c的最大公约数是c,故c为a和b的最大公约数。
辗转相除法是一个递归的算法,其时间复杂度为o(log max(a,b)),大多数情况下够用了。
int gcd(int a,int b){ if(b==0) return a; gcd(b,a%b);}
二:素数问题
素数也称质数,指除了1和其本身外再无别的因数的数。一般判定一个数是否是素数,通常我们会从2到√n遍历,若有能整除n的数则说明n不是素数。算法时间为o(√n),看起爱还可以,但若是给你一串数求其中素数的个数,那么这种算法就显得low了。有人机智的提出了素数筛。
将2到n之间的整数记录下来,其中最小的素数是2,将表中2的倍数全部不划去,表中剩余的最小的数字为3,再将3的倍数全划去,以此类推,就能找到所有的素数。这样做的时间复杂度只有o(nlog log n)。
int prime[MAXN+1]; //用于记录每个素数bool is_prime[MAXN+1];//值为true即为素数int sieve(int n){ int p=0; for(int i=1;i<=n;i++) is_prime[i]=true; is_prime[0]=false; is_prime[1]=false; for(int i=2;i<=n;i++) { if(is_prime[i]) { prime[p++]=i; //将素数记录到prime中 for(int j=2*i;j<=n;j+=i) //素数i的倍数的is_prime值全部改为false; is_prime[j]=false; } } return p;}
上述代码是求从1到n的素数,若是求[a,b)范位内的素数怎么求呢?
原理也是一样,开一个[1,b)的is_prime[ ]数组,按照相同的素数筛处理,最后找在[a,b)范围内的素数即可。
三:快速幂取模
数论问题经常遇见非常大的数,例如 X ^ 22,通常的思路是采用for循环,但当数很大时运算效率会很低。
采用快速幂算法可以将X^22拆为X^16 , X^4和X^2。时间复杂度直降至o(log n)。
typedef long long ll;ll quick_pow(ll x,ll n,ll mod){ ll ans=1; while(n>0) { if(n&1) ans=ans*x%mod; x=x*x%mod; n>>=1; } return ans;}
- 基础篇——数论基础
- 数论——基础概念
- 数论——组合数(基础)
- 数论基础
- 数论基础
- 数论 基础
- 数论基础
- 数论基础
- 数论基础
- 基础数论
- 基础数论
- 数论基础
- 数论基础
- 数论基础
- 数论基础
- 数论基础
- 数论基础
- 数论基础
- 文件操作
- 项目从mysql移植到SQL sqlserver问题汇总
- jquery图片轮播,三种方式
- Xcode 报错: value of type InerfaceController does not conform to HKWorkoutSessionDelegate in assignmen
- HDU 1500 Chopsticks(动态规划)
- 基础篇——数论基础
- POJ 2251Dungeon Master
- Web Uploader图片上传 java实现
- VC6.0工程设置
- android监听应用缓存和任务栈顶的方法
- java设计模式:观察者模式实例详解(基于java内置观察者)
- 对单一职责原则的理解
- Method Swizzling(iOS的hook机制)
- 用js根据当前季度获取上一季度