题意:根据题给公式,求出第n项的值
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565
思路:矩阵快速幂,公式简化过程见 http://blog.youkuaiyun.com/crazy______/article/details/9021169 ,用快速幂模板即可。
注意点:第一次做矩阵快速幂的题,用struct封装数组,使数组能够成为函数的返回值。
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
12486525 | 2014-12-13 14:39:46 | Accepted | 4565 | 249MS | 1196K | 2043 B | G++ | luminous11 |
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#define ll long long
#define ull unsigned long long
#define all(x) (x).begin(), (x).end()
#define clr(a, v) memset( a , v , sizeof(a) )
#define pb push_back
#define mp make_pair
#define read(f) freopen(f, "r", stdin)
#define write(f) freopen(f, "w", stdout)
using namespace std;
struct matrix{
ll num[3][3];
};
ll m;
matrix mul ( matrix a, matrix b, ll n )
{
matrix c;
memset ( c.num, 0, sizeof ( c.num ) );
for ( int i = 0; i < n; i ++ )
{
for ( int j = 0; j < n; j ++ )
{
if ( ! a.num[j][i] )continue;
for ( int k = 0; k < n; k ++ )
{
if ( ! b.num[i][k] )continue;
c.num[j][i];
c.num[j][k] = ( c.num[j][k] + a.num[j][i] * b.num[i][k] + m ) % m;
}
}
}
return c;
}
matrix pow_mod ( matrix a, ll b, ll n )
{
matrix tmp;
memset ( tmp.num, 0, sizeof ( tmp.num ) );
for ( int i = 0; i < n; i ++ )
tmp.num[i][i] = 1;
while ( b )
{
if ( b & 1 )
{
tmp = mul( tmp, a, n );
}
a = mul ( a, a, n );
b >>= 1;
}
return tmp;
}
int main()
{
ll a, b, n;
while ( cin >> a >> b >> n >> m )
{
if ( n == 1 )
{
cout << 2 * a % m << endl;
continue;
}
matrix c;
memset ( c.num, 0, sizeof ( c.num ) );
c.num[0][0] = 2 * a;
c.num[0][1] = b - a * a;
c.num[1][0] = 1;
matrix d = pow_mod ( c, n - 1, 2 );
cout << ( ( d.num[0][0] * 2 * a + d.num[0][1] * 2 ) % m + m ) % m << endl;
}
return 0;
}