zoukankan      html  css  js  c++  java
  • *HDU 1757 矩阵乘法

    A Simple Math Problem

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4307    Accepted Submission(s): 2586


    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
     
    Author
    linle
     
    Source
     
    题意:
    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 .
    上面的递推式计算f(k)。计算结果%m;
    代码:
     1 //普通递推会超时,用矩阵乘法。构造矩阵时右上角的(n-1)*(n-1)矩阵置为单位矩阵,第n行从 右 到 左 填入系数,快速幂之后第n行作为行矩阵乘递推式从 小 到 大 排列的列矩阵得到结果
     2 //或者构造左下角的单位矩阵,第一行从 左 到 右 填入系数,快速幂之后第1行作为行矩阵乘递推式从 大 到 小 排列的列矩阵得到结果
     3 #include<bitsstdc++.h>
     4 using namespace std;
     5 int a[12],f[12]={0,1,2,3,4,5,6,7,8,9};
     6 int k,m;
     7 struct Lu
     8 {
     9     int mp[12][12];
    10 }L1;
    11 void init()
    12 {
    13     memset(L1.mp,0,sizeof(L1.mp));
    14     for(int i=0;i<=8;i++)
    15     {
    16         L1.mp[i][i+1]=1;
    17     }
    18     for(int i=0;i<=9;i++)
    19     {
    20         L1.mp[9][i]=a[9-i];
    21     }
    22 }
    23 Lu mult(Lu a,Lu b)
    24 {
    25     Lu c;
    26     for(int i=0;i<=9;i++)
    27     for(int j=0;j<=9;j++)
    28     {
    29         c.mp[i][j]=0;
    30         for(int k=0;k<=9;k++)
    31         c.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%m;
    32         c.mp[i][j]%=m;
    33     }
    34     return c;
    35 }
    36 Lu solve(int x)
    37 {
    38     if(x==1)
    39     return L1;
    40     if(x&1)
    41     {
    42         Lu q=solve(x-1);
    43         return mult(q,L1);
    44     }
    45     else
    46     {
    47         Lu q=solve(x/2);
    48         return mult(q,q);
    49     }
    50 }
    51 int main()
    52 {
    53     while(scanf("%d%d",&k,&m)!=EOF)
    54     {
    55         for(int i=0;i<=9;i++)
    56         scanf("%d",&a[i]);
    57         if(k<10)
    58         {
    59             printf("%d
    ",k%m);
    60             continue;
    61         }
    62         init();
    63         Lu tem=solve(k-9);
    64         int ans=0;
    65         for(int i=0;i<=9;i++)
    66         ans+=(tem.mp[9][i]*f[i])%m;
    67         printf("%d
    ",ans%m);
    68     }
    69     return 0;
    70 }
     1 //普通递推会超时,用矩阵乘法。
     2 #include<bitsstdc++.h>
     3 using namespace std;
     4 int a[12],f[12]={9,8,7,6,5,4,3,2,1,0};
     5 int k,m;
     6 struct Lu
     7 {
     8     int mp[12][12];
     9 }L1;
    10 void init()
    11 {
    12     memset(L1.mp,0,sizeof(L1.mp));
    13     for(int i=1;i<=9;i++)
    14     {
    15         L1.mp[i][i-1]=1;
    16     }
    17     for(int i=0;i<=9;i++)
    18     {
    19         L1.mp[0][i]=a[i];
    20     }
    21 }
    22 Lu mult(Lu a,Lu b)
    23 {
    24     Lu c;
    25     for(int i=0;i<=9;i++)
    26     for(int j=0;j<=9;j++)
    27     {
    28         c.mp[i][j]=0;
    29         for(int k=0;k<=9;k++)
    30         c.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%m;
    31         c.mp[i][j]%=m;
    32     }
    33     return c;
    34 }
    35 Lu solve(int x)
    36 {
    37     if(x==1)
    38     return L1;
    39     if(x&1)
    40     {
    41         Lu q=solve(x-1);
    42         return mult(q,L1);
    43     }
    44     else
    45     {
    46         Lu q=solve(x/2);
    47         return mult(q,q);
    48     }
    49 }
    50 int main()
    51 {
    52     while(scanf("%d%d",&k,&m)!=EOF)
    53     {
    54         for(int i=0;i<=9;i++)
    55         scanf("%d",&a[i]);
    56         if(k<10)
    57         {
    58             printf("%d
    ",k%m);
    59             continue;
    60         }
    61         init();
    62         Lu tem=solve(k-9);
    63         int ans=0;
    64         for(int i=0;i<=9;i++)
    65         ans+=(tem.mp[0][i]*f[i])%m;
    66         printf("%d
    ",ans%m);
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    oracle空表导出的问题
    虚拟机连不上网
    mongodb查询返回内嵌符合条件的文档
    gson转换带有objectId的问题
    java部署项目,ip访问不到,localhost能访问到,浏览器启用了代理的问题
    mongodb replica set(副本集)设置步骤
    a different object with the same identifier value was already associat
    头文件.h的应用以及fortran和c的混合编程
    Matlab符号运算总结
    fortran自由格式每行最多编写132个字符
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/6087345.html
Copyright © 2011-2022 走看看