题目链接:
HDU 4990 Reading comprehension
/*
*题意:
*规定:当n为偶数时a[n]=2*a[n-1],n为奇数时a[n]=2*a[n-1]+1(n>1),且a[0]=0.
*给出n和m求出a[n]%m的值,其中1<=n,m<=1e9.
*
*分析:
*由于n,m太大,时间限制是1000ms,如果是普通的递推的话,应该会TLE。所以用矩阵解决
*构造矩阵
* 0 1 0 0
* A=1 0 0 和 B= 1
* 0 1 2 a[0]
* 然后用A^n乘以矩阵B得到矩阵C,答案就是C[3][1]。
*/
//1424K 15MS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long n,m;
struct Matrix{
int row,col;
long long data[15][15];
};
void init(Matrix& x)
{
x.row=x.col=3;
x.data[1][2]=x.data[2][1]=x.data[3][2]=1;
x.data[1][1]=x.data[1][3]=x.data[2][2]=x.data[2][3]=x.data[3][1]=0;
x.data[3][3]=2;
}
Matrix multiply(Matrix a,Matrix b,long long mod)
{
Matrix ans;
ans.row=a.row;
ans.col=b.col;
memset(ans.data,0,sizeof(ans.data));
for(int i=1;i<=ans.row;i++){
for(int j=1;j<=ans.col;j++){
for(int k=1;k<=a.col;k++){
ans.data[i][j]+=a.data[i][k]*b.data[k][j];
ans.data[i][j]%=mod;
}
}
}
return ans;
}
Matrix quick_power(Matrix a,long long n,long long m)
{
Matrix ans,tmp=a;
ans.row=a.row,ans.col=a.col;
memset(ans.data,0,sizeof(ans.data));
for(int i=1;i<=ans.row;i++) ans.data[i][i]=1;
while(n){
if(n&1) ans=multiply(ans,tmp,m);
tmp=multiply(tmp,tmp,m);
n>>=1;
}
return ans;
}
int main()
{
while(~scanf("%I64d %I64d",&n,&m)){
Matrix a,b;
init(a);
a=quick_power(a,n,m);
b.row=3,b.col=1;
b.data[1][1]=0,b.data[2][1]=1,b.data[3][1]=0;
b=multiply(a,b,m);
printf("%I64d\n",b.data[3][1]);
}
}