UVA 10870 Recurrences 矩阵乘法

来源:互联网 发布:如何下载autocad软件 编辑:程序博客网 时间:2024/05/22 00:34

题目:

Consider recurrent functions of the following form:

f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + … + adf(n − d), for n > d,
where a1, a2, … , ad are arbitrary constants.
A famous example is the Fibonacci sequence, defined as: f(1) = 1, f(2) = 1, f(n) = f(n − 1) +
f(n − 2). Here d = 2, a1 = 1, a2 = 1.
Every such function is completely described by specifying d (which is called the order of recurrence),
values of d coefficients: a1, a2, … , ad, and values of f(1), f(2), … , f(d). You’ll be given these numbers,
and two integers n and m. Your program’s job is to compute f(n) modulo m.
Input
Input file contains several test cases. Each test case begins with three integers: d, n, m, followed by
two sets of d non-negative integers. The first set contains coefficients: a1, a2, … , ad. The second set
gives values of f(1), f(2), … , f(d).
You can assume that: 1 ≤ d ≤ 15, 1 ≤ n ≤ 2
31 − 1, 1 ≤ m ≤ 46340. All numbers in the input will
fit in signed 32-bit integer.
Input is terminated by line containing three zeroes instead of d, n, m. Two consecutive test cases
are separated by a blank line.
Output
For each test case, print the value of f(n)( mod m) on a separate line. It must be a non-negative integer,
less than m.
Sample Input
1 1 100
2
1
2 10 100
1 1
1 1
3 2147483647 12345
12345678 0 12345
1 2 3
0 0 0
Sample Output
1
55
423

思路:

如同fib数列一样,求出第n项的结果,蛮力递推肯定不行的,这里我们用矩阵乘法来优化,矩阵乘法的用法参考如下:
http://blog.csdn.net/qq_27508477/article/details/47663185

这里只是做了一个延伸,把矩阵从二维变道了多维。

代码:

#include "iostream"#include"stdlib.h"#include"cstdio"#include"cstring"using namespace std;typedef long long int lint;lint bc=0;lint mod=0;lint a[20];lint f[20];struct matrix{    lint x[20][20];};matrix mut_matrix(matrix a,matrix b){    matrix temp;    memset(temp.x,0,sizeof(temp.x));    for(lint i=1; i<=bc; i++)    {        for(lint j=1; j<=bc; j++)        {            for(lint k=1; k<=bc; k++)            {                temp.x[i][j]=((a.x[i][k]%mod)*(b.x[k][j])%mod)%mod+temp.x[i][j];                temp.x[i][j]%=mod;            }        }    }    return temp;}matrix pow_matrix(matrix a,lint b){    matrix ans;    memset(ans.x,0,sizeof(ans));    for(lint i=1; i<=bc; i++)        ans.x[i][i]=1;    while(b)    {        if(b%2==1) ans=mut_matrix(ans,a);        a=mut_matrix(a,a);        b=b/2;    }    return ans;}int main(){    lint n; //求fn    //freopen("in.txt","r",stdin);    while(scanf("%lld %lld %lld",&bc,&n,&mod)!=EOF)    {        if(bc==0&&n==0&&mod==0)    break;        matrix st;        matrix tp;        memset(st.x,0,sizeof(st.x));        memset(tp.x,0,sizeof(tp.x));        for(lint i=1; i<=bc; i++)        {            scanf("%Illd",&a[i]);        }        for(lint i=1; i<=bc; i++)        {            scanf("%lld",&f[i]);        }        for(lint i=1; i<=bc; i++)        {            tp.x[1][i]=a[i];        }        for(lint i=1; i<=bc-1; i++)        {            tp.x[i+1][i]=1;        }        for(int i=1; i<=bc; i++)        {            st.x[i][1]=f[bc-i+1];        }        if(n<=bc)   printf("%lld\n",f[n]);        else        {            matrix tt=pow_matrix(tp,n-bc);            matrix ans=mut_matrix(tt,st);            printf("%lld\n",ans.x[1][1]);        }    }    return 0;}

最简单的就是拿fib数列去做测试证明。

0 0
原创粉丝点击