快速幂,是真的香!!!
快速幂
快速幂:顾名思义就是用来计算一个数的次方的时候使用的。
我们算x的n次方的时候,我们一般没有接触到快速幂的时候都会用while或者是for循环,循环n次;
或者使用math头文件中的pow函数来直接计算;
但是我们某一天发现数特别大的时候,以上这两种方法他会超时,这是我们就会寻找到一种解决这种问题的算法——快速幂。
这里我们先列举一道题,我们学完这个知识后,我们用快速幂干掉他!!!
DNA是所有真核生物的遗传物质,它由四种碱基组成。现在科学家要设计单链DNA,要穷
举给定规定长度的DNA的所有组成方法。现在给你计算长度在N到M的单链DNA的组成方
法数(DNA每个单位长度都有四种组成可能)。
输入描述:
输入包括两个整数N,M(1<=N<=M<=1e18)其中(M-N<=1e5)
输出描述:
输出包括一个整数,输出记录所有DNA的组成的方案数。答案对1e9+7取模。
输入
2 4
输出
336
说明
4^2 + 4^3 + 4^4 = 336
快速幂思想
比如去求2^9
= 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2
= (2 ^ 2) * (2 ^ 2) * (2 ^ 2) * (2 ^ 2) * 2
= (2 ^ 4) * (2 ^ 4) * 2
对于取模
a * b % m = [(a % m) * (b % m)] % m
a ^ b % m
= (a % m) * (a % m) * (a % m) * ......%m
=(a % m) ^ b % m
我们在这里写一下板子
int ppow(int a, int k)// a ^ k
{
int m = 1;
while(k)
{
if(k % 2)//如果k是奇数,执行这部操作;k为偶数,直接越过
m *= a;
a *= a;
k /= 2;//k此后一直为偶数,直到0
}
return m;
}
取模
int mod = 1e7 + 9;
int ppow(int a, int k)
{
int m = 1;
a %= mod;
while(k)
{
if(k % 2)
m = (m * a) % mod;
a = (a * a) % mod;
k /= 2;
}
return m;
}
现在我们就可以用模板解题了!!!
学废了吗,小伙伴?
代码在这里,开动了吧!
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL ppow(LL a, LL k)
{
LL m = 1;
while (k)
{
if(k % 2) m = (m * a) % mod;
a = (a * a) % mod;
k /= 2;
}
return m % mod;
}
int main()
{
LL n,h;
cin >> n >> h;
LL sum = 0;
LL m = ppow(4, n);//先求出来4^n
for (int i = 0; i <= h - n; i ++)//再循环每次m = m * 4
{
sum = (sum + m) % mod;
m *= 4;
m = m % mod;
}
cout << sum << endl;
return 0;
}//这样时间复杂度比for(int i = n; i <= h; i++)里面再进行快速幂(会超时)快得多