HDU 2842 矩阵快速幂
题目
链接
根据题意推出公式:
,然后利用矩阵快速幂。
由上面公式可知,初始矩阵为
,幂次矩阵为
,可以在
级别的复杂度求出
.
代码:
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
const int mod = 200907;
typedef long long LL;
const int m_size = 3;
const int m_max = 5;
struct node
{
LL d[m_max][m_max];
};
node matrixm(node a, node b)
{
node ans;
for(int i = 0; i < m_max; i++)
for(int j = 0; j < m_max; j++)
ans.d[i][j] = 0;
for(int j = 0; j <m_size; j++)
for(int k = 0; k <m_size; k++)
ans.d[0][j] = (ans.d[0][j]+a.d[0][k]*b.d[k][j])%mod;
return ans;
}
node matrixw(node a, node b)
{
node ans;
for(int i = 0; i < m_max; i++)
for(int j = 0; j < m_max; j++)
ans.d[i][j] = 0;
for(int i = 0; i < m_size; i++)
for(int j = 0; j <m_size; j++)
for(int k = 0; k <m_size; k++)
ans.d[i][j] = (ans.d[i][j]+a.d[k][j]*b.d[i][k])%mod;
return ans;
}
void initres(node &res)
{
for(int i = 0; i < m_max; i++)
for(int j = 0; j < m_max; j++)
res.d[i][j] = 0;
res.d[0][0] = 1;res.d[0][1] = 1;res.d[0][2] = 0;
res.d[1][0] = 2;res.d[1][1] = 0;res.d[1][2] = 0;
res.d[2][0] = 1;res.d[2][1] = 0;res.d[2][2] = 1;
return ;
}
void initans(node &ans)
{
for(int i = 0; i < m_max; i++)
for(int j = 0; j < m_max; j++)
ans.d[i][j] = 0;
ans.d[0][0] = 2;ans.d[0][1] = 1;ans.d[0][2] = 1;
return ;
}
node ppow(node an, node re,LL k)
{
node ans = an;
node res = re;
while(k)
{
if(k&1)
ans = matrixm(ans, res);
res = matrixw(res, res);
k >>= 1;
}
return ans;
}
int main()
{
LL n;
node ans, res;
initans(ans);
initres(res);
while(scanf("%lld", &n)&&n)
{
if(n==1)
{
printf("1\n");
}
else if(n==2)
{
printf("2\n");
}
else
{
node fans = ppow(ans,res,n-2);
printf("%lld\n", fans.d[0][0]);
}
}
return 0;
}