库函数pow是用朴素算法对浮点型数据进行幂运算的,时间复杂度为o(n),计算比较大的数可能会超时和数据溢出;
//*************快速幂计算****************************************
朴素算法实现:
ll get_pow(ll x, ll n) //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可)
{
ll ans=1;
while(n--)
{
ans*=x%MAX;
ans%=MAX;
}
return ans;
}
快速幂算法:
原理:
二分:
假设我们现在要计算pow(x,n),那么有当n为偶数时pow(x, n)==pow(x*x, n/2),当n为奇数时,pow(x, n)==pow(x, n-1)*x, 此时n-1为偶数,可按前面的公式继续迭代;
循环往复,即可计算出答案;
二进制:
计算pow(x,n),先将n转化为二进制形式,n=2^a+2^b....
例如:计算pow(x,21),19=2^4+2^2+2^1;其中2^2可以由(2^1)*(2^1)得到,同理, 2^4可以由(2^2)*(2^2)得到;
所有有pow(x,21)==x^(2^4+2^2+2^1),其时间复杂度为o(long2(n));
以上两种思路的出发点不同,不过其本质一致,代码也相同;
代码:
ll get_pow(ll x, ll n) //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可)
{
int ans=1;
while(n)
{
if(n&1)
{
ans=(ans*x)%MAX;
}
x=(x*x)%MAX;
n>>=1;
}
return ans;
}
//*********************矩阵快速幂计算**********************************
矩阵快速幂和快速幂算法原理一样,只是操作对象换成了矩阵;
http://acm.nyist.net/JudgeOnline/problem.php?pid=148(题目链接)
ac代码:
#include <bits/stdc++.h>
#define MAXN 2
#define mod 10000
#define ll long long
using namespace std;
struct Matrix
{
ll x[MAXN][MAXN];
};
Matrix temp={1, 1, 1, 0};
ll n; //***n为幂数,结果对mod取模
Matrix multi(Matrix a, Matrix b) //***矩阵乘法
{
Matrix c;
memset(c.x, 0, sizeof(c.x));
for(int i=0; i<MAXN; i++)
{
for(int j=0; j<MAXN; j++)
{
for(int k=0; k<MAXN; k++)
{
c.x[i][j]+=(a.x[i][k]*b.x[k][j])%mod;
}
}
}
return c;
}
ll Pow(ll n)
{
Matrix ans;
temp.x[0][0]=temp.x[0][1]=temp.x[1][0]=1;
temp.x[1][1]=0;
memset(ans.x, 0, sizeof(ans.x));
ans.x[0][0]=ans.x[1][1]=1;
while(n)
{
if(n&1) ans=multi(ans, temp);
temp=multi(temp, temp);
n>>=1;
}
return ans.x[0][1];
}
int main(void)
{
std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
while(cin >> n && n!=-1)
{
cout << Pow(n)%mod << endl;
}
return 0;
}