uva10870 Recurrences矩阵快速幂

来源:互联网 发布:北京时间网络触屏版 编辑:程序博客网 时间:2024/05/15 23:53

点击打开链接

f[n]=a1*f[n-1]+a2*f[n-2]+...+ad*f[n-d]; 

由于n太大,不能直接递推,需要用矩阵快速幂来解决,时间复杂度为O(d^3logn)

举例,d=5的矩阵关系式为:

|a1 a2 a3 a4 a5|    | f[n]   |   | f[n+1] | 

|1             |    | f[n-1] |   | f[n]   | 

|   1          | *  | f[n-2] | = | f[n-1] | (空白处为0) 

|      1       |    | f[n-3] |   | f[n-2] | 

|         1    |    | f[n-4] |   | f[n-3] |

#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<iomanip>#include<map>#include<algorithm>#include<queue>#include<set>#define inf 1000000000#define pi acos(-1.0)#define eps 1e-8#define seed 131using namespace std;typedef pair<int,int> pii;typedef unsigned long long ull;typedef long long ll;const int maxn=100005;ll d,n,m;struct mat{    ll e[16][16];};ll f[16];mat a,s;mat mul(mat p,mat q){    mat c;    for(int i=1;i<=d;i++)    {        for(int j=1;j<=d;j++)        {            c.e[i][j]=0;            for(int k=1;k<=d;k++)            {                c.e[i][j]=(c.e[i][j]+p.e[i][k]*q.e[k][j]%m)%m;            }        }    }    return c;}void powMat(mat u,ll b)//计算u^b{    while(b)    {        if(b&1)            s=mul(s,u);        u=mul(u,u);        b=(b>>1);    }}int main(){    while(cin>>d>>n>>m)    {        if(d==0&&n==0&&m==0)            break;        memset(a.e,0,sizeof(a.e));        memset(s.e,0,sizeof(s.e));        for(int i=1;i<=d;i++)        {            cin>>a.e[1][i];        }        for(int i=1,j=d;i<=d;i++,j--)            cin>>f[j];        for(int i=2;i<=d;i++)        {            a.e[i][i-1]=1;            s.e[i][i]=1;        }        s.e[1][1]=1;        powMat(a,n-d);        ll ans=0;        for(int i=1;i<=d;i++)        {            ans=(ans+s.e[1][i]*f[i]%m)%m;        }        cout<<ans<<endl;    }    return 0;}



0 0
原创粉丝点击