HDU - 4990 Reading comprehension(矩阵快速幂)
题目:
Read the program below carefully then answer the question.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>
const int MAX=100000*2;
const int INF=1e9;
int main()
{
int n,m,ans,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=0;
for(i=1;i<=n;i++)
{
if(i&1)ans=(ans*2+1)%m;
else ans=ans*2%m;
}
printf("%d\n",ans);
}
return 0;
}
Input
Multi test cases,each line will contain two integers n and m. Process to end of file.
[Technical Specification]
1<=n, m <= 1000000000
Output
For each case,output an integer,represents the output of above program.
Sample Input
1 10 3 100
Sample Output
1 5
解决过程:
先用题目中给的程序跑出来前几项1,2,5,10,21,42,85,170。然后接下来就是玄学找规律了,找不找的到就看缘分了。是在不行就用无敌找规律网站直接爆出来。经过不懈努力,发现规律就是F(n)=F(n-1)+2*F(n-2)+1。知道递推式了就很明显的矩阵快速幂了。
直接矩阵快速幂板子干上,结束。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <list>
#include <cstdlib>
#include <memory>
#include <cstring>
#include <sstream>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define PI 3.141592653579
#define FRER() freopen("input.txt" , "r" , stdin);
#define FREW() freopen("output.txt" , "w" , stdout);
#define QIO std::ios::sync_with_stdio(false)
const double eps = 1e-8;
typedef long long ll;
const int maxn = 3+10;
ll mod;
struct matrix
{
ll x[3][3];
void init()
{ memset(x , 0 , sizeof(x)); }
};
matrix mul(matrix a, matrix b)
{
matrix c;
c.init();
for( int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
c.x[i][j] += a.x[i][k] * b.x[k][j];
c.x[i][j] %= mod;
}
return c;
}
matrix powe(matrix x, ll n)
{
matrix r;
r.init();
r.x[1][1] = r.x[0][0] = r.x[2][2] = 1;
while(n)
{
if(n & 1)
r = mul(r , x);
x = mul(x , x);
n >>= 1;
}
return r;
}
int main()
{
// FRER();
// FREW();
QIO;
int n ;
while(cin >> n >> mod)
{
matrix a , b;
a.init();
b.init();
a.x[0][0] = 1; a.x[0][1] = 2;
a.x[0][2] = 1; a.x[1][0] = 1;
a.x[2][2] = 1; b.x[0][0] = 2;
b.x[1][0] = 1; b.x[2][0] = 1;
if(n == 1)
{printf("%lld\n" , 1%mod);continue;}
if(n == 2)
{printf("%lld\n" , 2 % mod); continue;}
matrix res;
res = powe(a, n-2);
res = mul(res , b);
printf("%lld\n" , res.x[0][0]);
}
}