zoukankan      html  css  js  c++  java
  • HDU1757:A Simple Math Problem(矩阵快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=1757

    Problem Description
    Lele now is thinking about a simple function f(x).
    If x < 10  f(x) = x.
    If x >= 10  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
    And ai(0<=i<=9) can only be 0 or 1 .
    Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
     
    Input
    The problem contains mutiple test cases.Please process to the end of file.
    In each case, there will be two lines.
    In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
    In the second line , there are ten integers represent a0 ~ a9.
     
    Output
    For each case, output f(k) % m in one line.
    Sample Input
    10 9999
    1 1 1 1 1 1 1 1 1 1
    20 500
    1 0 1 0 1 0 1 0 1 0
     
    Sample Output
    45
    104
     
    题目解析:
    前面已经写了一篇博客如何构造矩阵,这道题可以说就是上片博客的简单应用。
    矩阵的乘法不满足交换律,但是却满足结合律,如:A*B*C=A*(B*C);

    f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
    构造的矩阵是:
    |0 1 0 ......... 0|    |f0|   |f1 |
    |0 0 1 0 ...... 0|    |f1|   |f2 |
    |...................1| *  |..| = |...|
    |a9 a8 .......a0|    |f9|   |f10|

    然后根据矩阵的结合律,可以先把构造的矩阵的K次幂求出来。最后直接求第一个数。

    代码:
    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct ma
    {
        int a[10][10];
    } init,res;
    int K;
    int mod,b[10],f[10];
    ma Mul(ma x,ma y)
    {
        ma tmp;
        for(int i=0; i<10; i++)
            for(int j=0; j<10; j++)
            {
                tmp.a[i][j]=0;
                for(int k=0; k<10; k++)
                    tmp.a[i][j]=(tmp.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
            }
        return tmp;
    }
    ma Pow(ma x,int K)
    {
        ma tmp;
        for(int i=0; i<10; i++)
        {
            for(int j=0; j<10; j++)
                tmp.a[i][j]=(i==j);
        }
        while(K!=0)
        {
            if(K&1)
                tmp=Mul(tmp,x);
            K>>=1;
            x=Mul(x,x);
        }
        return tmp;
    }
    int main()
    {
        while(scanf("%d%d",&K,&mod)!=EOF)
        {
            for(int i=0; i<=9; i++)
            {
                scanf("%d",&init.a[9][9-i]);
            }
            if(K<=9)
            {
                printf("%d
    ",K);
                continue;
            }
            for(int i=0; i<10; i++)
                f[i]=i;
            for(int i=0; i<=8; i++)
            {
                for(int j=0; j<=9; j++)
                    init.a[i][j]=(i==j-1);
            }
            res=Pow(init,K);
            int ans=0;
            for(int j=0; j<10; j++)
            {
                ans=(ans+res.a[0][j]*j)%mod;
            }
            printf("%d
    ",ans);
    
        }
        return 0;
    }

     加深印象,写了两次。

    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct ma
    {
        int a[10][10];
    } init,res;
    int K;
    int mod,b[10],f[10];
    ma Mul(ma x,ma y)
    {
        ma tmp;
        for(int i=0; i<10; i++)
            for(int j=0; j<10; j++)
            {
                tmp.a[i][j]=0;
                for(int k=0; k<10; k++)
                    tmp.a[i][j]=(tmp.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
            }
        return tmp;
    }
    ma Pow(ma x,int K)
    {
        ma tmp;
        for(int i=0; i<10; i++)
        {
            for(int j=0; j<10; j++)
                tmp.a[i][j]=(i==j);
        }
        while(K!=0)
        {
            if(K&1)
                tmp=Mul(tmp,x);
            K>>=1;
            x=Mul(x,x);
        }
        return tmp;
    }
    int main()
    {
        while(scanf("%d%d",&K,&mod)!=EOF)
        {
            for(int i=0; i<=9; i++)
            {
                scanf("%d",&init.a[9][9-i]);
            }
            if(K<=9)
            {
                printf("%d
    ",K);
                continue;
            }
            for(int i=0; i<10; i++)
                f[i]=i;
            for(int i=0; i<=8; i++)
            {
                for(int j=0; j<=9; j++)
                    init.a[i][j]=(i==j-1);
            }
            res=Pow(init,K-9);
            int ans=0;
            for(int j=0; j<10; j++)
            {
                ans=(ans+(res.a[9][j])*f[j])%mod;
            }
            printf("%d
    ",ans);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode 258 Add Digits
    LeetCode 231 Power of Two
    LeetCode 28 Implement strStr()
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 21 Merge Two Sorted Lists
    LeetCode 20 Valid Parentheses
    图形处理函数库 ImageTTFBBox
    php一些函数
    func_get_arg(),func_get_args()和func_num_args()的用法
    人生不是故事,人生是世故,摸爬滚打才不会辜负功名尘土
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4132899.html
Copyright © 2011-2022 走看看