HDU 5015 233 Matrix (构造矩阵)

来源:互联网 发布:linux安装配置jenkins 编辑:程序博客网 时间:2024/06/03 14:31

题意:给出矩阵的第0行(233,2333,23333,...)和第0列a1,a2,...an(n<=10,m<=10^9),给出递推式: A[i][j] = A[i-1][j] + A[i][j-1],要求A[n][m]。

数据范围:n,m(n ≤ 10,m ≤ 109). 

思路:因为m ≤ 109显然是要找到列与列的递推关系,用logn幂加速。

从递推式可以得知:a[i][j]可以由a[1...i][j-1] 递推得到,所以构造递推矩阵实现a[1...1][j-1]向a[1...1][j]的转移‘即可

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;typedef long long  ll;const int mod = 10000007;struct mat{    ll a[15][15];    mat()    {        memset(a,0,sizeof(a));    }};ll I[15];mat S;int n,m;void print(mat m){    for(int i=1;i<=n;i++,puts(""))        for(int j=1;j<=n;j++)            printf("%d ",m.a[i][j]);}mat mul(mat m1,mat m2){    mat ans;    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            if(m1.a[i][j])                for(int k=1;k<=n;k++)                    ans.a[i][k]=( ans.a[i][k]+m1.a[i][j]*m2.a[j][k] )%mod;    return ans;}mat quickmul(mat m,int k){    mat ans;    for(int i=1;i<=n;i++) ans.a[i][i]=1;    while(k)    {        if(k&1) ans=mul(ans,m);        m=mul(m,m);        k>>=1;    }    return ans;}int main(){    while(~scanf("%d%d",&n,&m))    {        n+=2;        I[1]=23,I[n]=1;        for(int i=2;i<n;i++) scanf("%I64d",&I[i]);        for(int i=1;i<n;i++)//构造矩阵        {            S.a[i][1]=10;            for(int j=2;j<=i;j++) S.a[i][j]=1;            for(int j=i+1;j<n;j++) S.a[i][j]=0;            S.a[i][n]=3;        }        for(int i=1;i<=n;i++) S.a[n][i]=(i==n);        mat t=quickmul(S,m);        ll ans=0;        for(int i=1;i<=n;i++)            ans+=I[i]*t.a[n-1][i];        printf("%I64d\n",ans%mod);    }    return 0;}


0 0