zoukankan      html  css  js  c++  java
  • 【HDU5015】233 Matrix

    题意

    给出矩阵的第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]。

    分析

    推单位矩阵,先开始没想出来,于是看了题解,但是没有看懂,只有又自己推,然后发现就推出来了诶

    不要把菜当做不思考的借口

    第0列是告诉了的,忽略,从第1列开始看,第一列是

    233   

    a1

    a2

    a3

    a4

    ...

    an

    观察到第二列是2333,会出现一个3,于是我们干脆在每一列后面补一个3方便递推

    于是第一列和第二列分别是

    233                                                              2333

    a1                                                                             2333+a1

    a2                                                                             2333+a1+a2

    a3                                                                             2333+a1+a2+a3

    a4                                                                             2333+a1+a2+a3+a4

    ...                                                                 ...

    an                                                                             2333+a1+a2+...+an-1+an

    3                                                                  3

    想从第一列得到第二列,那需要乘什么呢?肯定是个n+2行n+2列的矩阵

    直接推发现2333=233*10+3

    于是第一行10 0 0 ...0 0 1

    2333+a1=233*10+3+a1

    于是第二行 10 1 0 ... 0 0 1

    类推可得到单位矩阵

    10 0 0 ...0 0 1

    10 1 0 ...0 0 1

    10 1 1 ...0 0 1

    10 1 1 ...1 0 1

    10 1 1 ...1 1 1

    0 0 0 ... 0 0 1

    将这个矩阵求m-1次方再与原来的第一列相乘,就可求出A[n][m],第1列用第0列推出

    或者是直接用第0列,求m次方

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 15
    #define ll long long
    #define mod 10000007
    ll n,m,f;
    ll one[N];
    struct email
    {
        ll x[N][N];
    }a,ans;
    
    inline void init()
    {
        one[0]=23;one[n+1]=3;
        for(ll i=1;i<=n;i++)scanf("%lld",&one[i]);
        memset(a.x,0,sizeof(a.x));
        for(ll i=0;i<=n;i++)a.x[i][0]=10,a.x[i][n+1]=1;
        a.x[n+1][n+1]=1;
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=i;j++)
                a.x[i][j]=1;
    }
    
    inline email mul(email a,email b)
    {
        email c;
        memset(c.x,0,sizeof(c.x));
        for(ll i=0;i<=n+1;i++)
            for(ll j=0;j<=n+1;j++)
                for(ll k=0;k<=n+1;k++)
                    c.x[i][j]+=a.x[i][k]*b.x[k][j],c.x[i][j]%=mod;
        return c;
    }
    
    inline email ksm(email a,ll m)
    {
        if(m==1)return a;
        email b=ksm(a,m/2);
        b=mul(b,b);
        if(m&1)b=mul(b,a);
        return b;
    }
    
    int main()
    {
        while(scanf("%lld%lld",&n,&m)==2)
        {
            init();
            ans=ksm(a,m);f=0;
            for(ll i=0;i<=n+1;i++)
                f+=ans.x[n][i]*one[i],f%=mod;
            printf("%lld
    ",f);
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9899540.html
Copyright © 2011-2022 走看看