您的位置:首页 > 其它

UVA Recurrences 矩阵相乘+快速幂

2015-03-23 20:58 295 查看
题目大意:

  f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d),已给递推公式,求f(n)的大小。

解题思路:

  n很大,所以我们就要构造矩阵,运用矩阵快速幂来求解。//题目描述上口口声声说int范围内,但是大家一定不要天真!!!!!!

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

#define LL long long
const int maxn = 18;
LL d, m;
struct mat
{
LL p[maxn][maxn];
};

mat mul (mat a, mat b);
mat pow (LL n, mat a, mat b);

int main ()
{
LL n;
mat a, b;

while (scanf ("%lld %lld %lld", &d, &n, &m), n+m+d)
{
memset (a.p, 0, sizeof(a.p));
memset (b.p, 0, sizeof(b.p));

for (int i=0; i<d; i++)//构造矩阵
{
scanf ("%lld", &a.p[i][0]);
a.p[i][0] %= m;
a.p[i][i+1] = 1;
}
for (int i=0; i<d; i++)//这个矩阵要反过来输入!!!!!!
{
scanf ("%lld", &b.p[0][d-i-1]);
b.p[0][i] %= m;
}

if (d < n)
{
b = pow (n-d, a, b);
printf ("%lld\n", b.p[0][0]);
}
else
printf ("%lld\n", b.p[0][d-n]);
}
return 0;
}

mat mul (mat a, mat b)
{
mat c;
memset (c.p, 0, sizeof(c.p));
for (int i=0; i<d; i++)
for (int j=0; j<d; j++)
{
for (int k=0; k<d; k++)
c.p[i][j] = (c.p[i][j] + a.p[i][k] * b.p[k][j]) % m;
}
return c;
}
mat pow (LL n, mat a, mat b)
{
while (n)
{
if (n % 2)
b = mul (b, a);
a = mul (a, a);
n /= 2;
}
return b;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: