【数学基础】快速幂
首先,顾名思义,快速幂就是快速的幂
不过可能有人晓得从math里头的pow(a,b),不过,这样的快速幂是没有灵魂的,我们要自己敲代码。
自己手敲幂,最简单的方法。代码如下
1 int power(int a,int b) 2 { 3 int ans=1; 4 for(int i=1;i<=b;i++) 5 { 6 ans*=a; 7 } 8 return ans; 9 }
这个比较基础的方法,的时间复杂度当然要比快速幂慢很多了,所以,我们要尝试降低时间复杂度。
开始前,不了解二进制和位运算符的请先来这里——>传送门
代码如下
1 int qpow(int a, int b){ 2 int ans=1, base=a; 3 while(b != 0){ 4 if (b%2) 5 ans*=base; 6 base*=base; 7 b>>=1; 8 } 9 return ans; 10 }
代码较短,很好理解。比如求a的11次方,只需要a1×a2×a8 就好了。
接下来,看几道例题:
1615:【例 1】序列的第 k 个数
BSNY 在学等差数列和等比数列,当已知前三项时,就可以知道是等差数列还是等比数列。现在给你序列的前三项,这个序列要么是等差序列,要么是等比序列,你能求出第 k 项的值吗。 如果第 k 项的值太大,对 200907 取模。
【输入格式】
第一行一个整数 T,表示有 T 组测试数据;
对于每组测试数据,输入前三项a,b,c,然后输入 k。
【输出格式】
对于每组数据输出第 k 项的值,对 200907 取模。
【样例输入】
2 1 2 3 5 1 2 4 5
【样例输出】
5 16
一道考验时间复杂度的题,找到规律就可以解决了。
代码如下
1 #include<iostream> 2 #define LL long long 3 using namespace std; 4 LL a, b, c, k, m=200907; 5 LL ans, base; 6 int T; 7 LL qpow(LL a, LL b, LL m){ 8 LL ans=1, base=a; 9 while(b != 0){ 10 if (b%2){ 11 ans*=base; 12 ans%=m; 13 } 14 base*=base; 15 base%=m; 16 b>>=1; 17 } 18 return ans; 19 } 20 void solve(){ 21 cin>>a>>b>>c>>k; 22 if (a-b == b-c){ 23 ans=0; 24 ans+=(b-a)*(k-1)+a; 25 if (ans>m) ans%=m; 26 } 27 else{ 28 base=(b/a)%m; 29 ans=a%m*qpow(base,k-1, m)%m; 30 } 31 cout<<ans<<endl; 32 } 33 int main() 34 { 35 cin>>T; 36 for (int i=1; i<=T; i++) solve(); 37 return 0; 38 }