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

    题面

    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

    思路

    直接看就是快速幂,我们关注一下这个2*1e9的数据量,这个数据量的话,复杂度肯定要降到log级别的,所以快速幂并木有错误。那么重点还是构造矩阵,我们让第一列是题目给的递推式子,其余为单位偏移作用。做n-9次的快速幂后和f1-f9去相乘就好啦。那么有几个细节注意,矩阵乘法的时候要取两遍的mod,然后最后的矩阵乘法不要写反,矩阵的相乘并不满足交换律,还有就是数组不要开小,会re。这些矩阵快速幂的题目都一个套路,我们真正要做的就是去把题目中隐含的或者直接给的递推式求出来,然后构造相应的辅助矩阵,最后完成快速幂就好。

    代码实现

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int inf =0x3f3f3f3f;
    const int maxn=11;
    struct Matrix {
        int maze[maxn][maxn];
        Matrix () {
            memset (maze,0,sizeof (maze));
        }
    };
    int n,mod;
    Matrix mul (Matrix a,Matrix b) {
        Matrix ans;
        for (int i=1;i<=10;i++) 
         for (int j=1;j<=10;j++){
           for (int k=1;k<=10;k++) 
               ans.maze[i][j]=(ans.maze[i][j]+(a.maze[i][k]*b.maze[k][j])%mod)%mod;
           }
           return ans;
    }
    Matrix fats_pow (Matrix a,int p) {
        Matrix ans;
        for (int i=1;i<=10;i++) ans.maze[i][i]=1;
        while (p) {
            if (p&1) ans=mul (ans,a);
            a=mul(a,a);
            p>>=1;
        }
        return ans;
    }
    int main () { 
        while (cin>>n>>mod) {
            Matrix fz;
            for (int i=1;i<=10;i++) cin>>fz.maze[i][1];
            for (int i=1;i<=9;i++) fz.maze[i][i+1]=1;
            if (n<10) {
                cout<<n%mod<<endl;
                continue;
            } 
            else {
                Matrix k;
                for (int i=1;i<=10;i++) k.maze[1][i]=10-i;
                fz=fats_pow (fz,n-9);
                k=mul (k,fz);
                cout<<k.maze[1][1]%mod<<endl;
            }
        }   
        return 0;
    }
    
  • 相关阅读:
    OpenCascade Ray Tracing Rendering
    Create New Commands in Tcl
    OpenCascade Modeling Algorithms Fillets and Chamfers
    OpenCascade Modeling Algorithms Boolean Operations
    Construction of Primitives in Open Cascade
    Open Cascade Data Exchange STL
    Tcl Tk Introduction
    Open Cascade DataExchange IGES
    Netgen mesh library : nglib
    Hello Netgen
  • 原文地址:https://www.cnblogs.com/hhlya/p/13288649.html
Copyright © 2011-2022 走看看