杨辉三角
常用性质:
(1)杨辉三角从第一行即n=0,开始有这样的性质每行所有数之和为2^n
(2)Cn1+Cn2+Cn3+..+Cnn=(2^n)-1; n=3时
3+3+1=2^3-1,刚好是第四行n=3的时候
快速幂
承接2^n,一般算法中n会很大,2^n很容易溢出,这时候题目会要求对运算结果取模。
//时间复杂度O(n)
const int module=1000000007;
int result=1;
for(int i=1;i<=n;i++){
if(result>module)result%=module;
result*=2;
}
以上代码在n=10^9时或更大时会出现运行慢的问题,为解决这个问题,提出快速幂算法 ,有递归和非递归
//时间复杂度O(logn)
//非递归快速幂
/* @params:n 表示幂 @param : m 表示底 @param : k 表示模 */
int quickpow(int n,int m,int k){
int b=1;
while(n>0){
if(n&1)b=(b*m)%k;
n=n>>1;
m=(m*m)%k;
//double=pow(m,n),表示(m^n),这个库函数不使用于n>30的 运算 这个库函数在math.h头文件中
//本题的大数运算,应该自己编写幂方函数
//为缩短运行时间采用快速幂
}
return b;
}
分治
1、什么是分治?
2、分治有哪些运用
3、参考链接:http://www.cnblogs.com/3910-xuyao/articles/4640953.html
4、非递归快速幂就是用到分治思想,解释如下:
这个用到二进制运算,n&1,按位与运算,1&1=1,1&0=0,0&0=0,n>>1左移1位,n每左一位相当于除2运算,n是m的幂,所以m=m^2,所以这里的分治体现是每次循环算出m=m^(2),在将每个小模块整合到b中,b=b+m,所以b=m*m^2*m^4*…..
* 这里补充一个,n|1 按位或运算,1|1=1, 1|0 =1, 0|0=0
组合数取模算法
参考链接http://blog.csdn.net/acdreamers/article/details/8037918
组合数数学表示:Cnm, n是C的下标,m是C的上标
公式表示:
组合数在acm中主要考察公式和防止溢出,解决溢出就用到取模
一句话,什么时候溢出什么时候取模
if(result>module)result%=module;
范例习题
题目:
这道题其实就是算Cn1+Cn2+Cn3+..+Cnn=(2^n)-1,这道题涉及了非递归快速幂以及大整数的取模
* 代码: *
#include<ctime>
#include<cstdio>
#include<cmath>
using namespace std;
const int module=1000000007;
int main(){
long long n;
while(scanf("%d",&n)){
long long b=1;
long long m=2;
int start=clock();
while(n>0){
if(n&1)b=(b%module)*(m%module);
n=n>>1;
m=(m)%module*(m%module)%module;
//double=pow(m,n),表示(m^n),这个库函数不使用于n>30的运算
//本题的大数运算,应该自己编写幂方函数
//为缩短运行时间采用快速幂
}
int end=clock();
double duration=(double)(end-start)/CLOCKS_PER_SEC;
printf("运行时间%f,运行结果%lld\n",duration,(b%module)-1);
}
return 0;
}
大家看答案可能觉得有点奇怪,100000000的值比1000还小,这是因为做了取模操作