码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5015 233 Matrix (构造矩阵)

时间:2015-04-10 11:33:56      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

题意:给出矩阵的第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;
}


HDU 5015 233 Matrix (构造矩阵)

标签:

原文地址:http://blog.csdn.net/kalilili/article/details/44975473

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!