zoukankan      html  css  js  c++  java
  • hdu 5015(矩阵快速幂z )

    a[i][j] = a[i-1][j] + a[i][j-1]

    m.特别大,可以计算出第一列,找出规律,构建一个特殊的矩阵,运用快速幂

    设矩阵x:

    1 0 0 0 ... |10 1 

    1 1 0 0 ... |10 1

    1 1 1 0 ...  |10 1

    1 1 1 1 ...   |10 1

    ......      ...  | ...

    0 0 0 0 ... |10 1

    0 0 0 0 ... | 0 1


    用最后两行来实现 233.....,求出x*第一列 = 第二列 。

    所以最终答案 = x ^ m * 第一列  (矩阵的运用很灵活)


    #include <cstdio>
    #include <cstring>
    #define mod 10000007
    typedef long long ll;
    int n;
    struct mat
    {
        ll q[16][16];
        mat()
        {
            memset(q,0,sizeof(q));
        }
    };
    
    mat mat_mul(mat a,mat b)
    {
        mat re;
        for(int i=0; i<=n; i++)
        {
            for(int j=0; j<=n; j++)
            {
                for(int k=0; k<=n; k++)
                {
                    re.q[i][j]+=a.q[i][k]*b.q[k][j];
                    re.q[i][j]%=mod;
                }
            }
        }
        return re;
    }
    
    mat mat_pow(mat m,int num)
    {
        mat re;
        mat tmp=m;
        for(int i=0; i<=n; i++)
        {
            re.q[i][i]=1;
        }
        while(num)
        {
            if(num&1)
            {
                re=mat_mul(re,tmp);
            }
            tmp=mat_mul(tmp,tmp);
            num>>=1;
        }
        return re;
    }
    
    int main()
    {
        int m;
        while(scanf("%d%d",&n,&m) != EOF)
        {
            mat p,orz;
            for(int i = 0; i < n; i++)
                scanf("%I64d",&p.q[i][0]);
            p.q[n][0] = 23;
            n++;
            p.q[n][0] = 3;
    
            for(int i=0; i<n-1; i++)
            {
                for(int j=0; j<=i; j++)
                {
                    orz.q[i][j]=1;
                }
                orz.q[i][n-1]=10;
                orz.q[i][n]=1;
            }
            orz.q[n][n] = orz.q[n-1][n] = 1;
            orz.q[n-1][n-1] = 10;
    
            mat tmp = mat_pow(orz,m);
            mat ans= mat_mul(tmp,p);
    
            printf("%I64d
    ",ans.q[n-2][0]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    合并区间
    编译与运行
    传递信息
    划分字母区间
    无重叠区间
    用最少数量的箭引爆气球
    根据身高重建队列
    二叉树展开为链表
    动态添加按钮
    基础知识
  • 原文地址:https://www.cnblogs.com/Przz/p/5409764.html
Copyright © 2011-2022 走看看