zoukankan      html  css  js  c++  java
  • 矩阵快速幂(HDU-1757&&HDU-2604)

    A Simple Math Problem HDU-1757

    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. 

    InputThe 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

    矩阵快速幂的关键是由F(n-1)、F(n-2)、F(n-3).....怎么得到F(n)、F(n-1)、F(n-2).....此题将F(n-1)、F(n-2)、F(n-3).....看成矩阵A,它们的系数看成矩阵B,因为F(n)=a0 * F(n-1) + a1 * F(n-2) + a2 * F(n-3) + …… + a9 * F(n-10),所以B矩阵第一行填a0、a1、a2.....a9。 第二行由F(n-1)、F(n-2)、F(n-3).....得到F(n-1),所以第二行填1 0 0 0.....以此类推,矩阵如下图所示:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 ll k,mod;
     7 struct node{
     8     int m[15][15];
     9 }a,b;
    10 void init()
    11 {
    12     memset(a.m,0,sizeof(a.m));
    13     memset(b.m,0,sizeof(b.m));
    14     for(int i=1;i<10;i++)
    15     {
    16         a.m[i][i-1]=1;
    17     }
    18     for(int i=0;i<10;i++)
    19     {
    20         b.m[i][i]=1;
    21     }
    22 }
    23 node mul(node aa,node bb)
    24 {
    25     node c;
    26     for(int i=0;i<10;i++)
    27     {
    28         for(int j=0;j<10;j++)
    29         {
    30             c.m[i][j]=0;
    31             for(int k=0;k<10;k++)
    32             {
    33                 c.m[i][j]+=(aa.m[i][k]*bb.m[k][j])%mod;
    34             }
    35             c.m[i][j]%=mod;
    36         }
    37     } 
    38     return c;
    39 }
    40 node pow_mod(node aa,node bb,int t)
    41 {
    42     while(t)
    43     {
    44         if(t&1)
    45         {
    46             bb=mul(aa,bb); 
    47         }
    48         aa=mul(aa,aa);
    49         t>>=1; 
    50     }
    51 return bb;
    52 }
    53 int main()
    54 {
    55     while(~scanf("%lld%lld",&k,&mod))
    56     {
    57         init();
    58         for(int i=0;i<10;i++)
    59         {
    60             scanf("%d",&a.m[0][i]);
    61         }
    62         if(k<=9)
    63         {
    64             printf("%d
    ",k%mod);
    65             continue;
    66         }
    67         else
    68         {
    69             node res=pow_mod(a,b,k-9);
    70             ll ans=0;
    71             for(int i=0;i<10;i++)
    72             {
    73                 ans+=res.m[0][i]*(9-i)%mod;
    74             }
    75             printf("%lld
    ",ans%mod);
    76         }
    77     }
    78 }
    79  

    心得:一般矩阵快速幂的题求某个矩阵的多少次幂是看该矩阵从第几项开始满足矩阵快速幂乘法的。比如这个题前九项并不满足矩阵乘法,所以pow_mod里面的幂项是k-9(一般是前多少项不满足就减几)。

    而pow_mod函数返回的值为矩阵乘完后的值,保存res.m[0][i]中,最后ans为res.m[0][i]与前多少项不满足矩阵乘法的项的值的乘积。

    Queuing  HDU-2604

    Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. 

      Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2 L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue. 
    Your task is to calculate the number of E-queues mod M with length L by writing a program. 

    InputInput a length L (0 <= L <= 10 6) and M.OutputOutput K mod M(1 <= M <= 30) where K is the number of E-queues with length L.Sample Input

    3 8
    4 7
    4 8

    Sample Output

    6
    2
    1

    本题的关键是推出f(n)=f(n-1)+f(n-3)+f(n-4)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 typedef long long ll;
      6 ll l,mod;
      7 struct node{
      8     int m[15][15];
      9 }a,b;
     10 void init()
     11 {
     12     memset(a.m,0,sizeof(a.m));
     13     for(int i=0;i<4;i++)
     14     {
     15         if(i!=1)
     16             a.m[0][i]=1;
     17     }
     18     for(int i=1;i<4;i++)
     19     {
     20         a.m[i][i-1]=1;
     21     }
     22     memset(b.m,0,sizeof(b.m));
     23     for(int i=0;i<4;i++)
     24     {
     25         b.m[i][i]=1;
     26     }
     27 }
     28 node mul(node aa,node bb)
     29 {
     30     node c;
     31     for(int i=0;i<4;i++)
     32     {
     33         for(int j=0;j<4;j++)
     34         {
     35             c.m[i][j]=0;
     36             for(int k=0;k<4;k++)
     37             {
     38                 c.m[i][j]+=(aa.m[i][k]*bb.m[k][j])%mod;
     39             }
     40             c.m[i][j]%=mod;
     41         }
     42     }
     43 return c;
     44 }
     45 node pow_mod(node aa,node bb,int x)
     46 {
     47     while(x)
     48     {
     49         if(x&1)
     50         {
     51             bb=mul(aa,bb);
     52         }
     53         aa=mul(aa,aa);
     54         x>>=1;
     55     }
     56 return bb;
     57 }
     58 int f[4]={2,4,6,9};
     59 int main()
     60 {
     61     while(~scanf("%lld%lld",&l,&mod))
     62     {
     63         init();
     64         if(l<=4)
     65         {
     66             if(l==0)
     67             {
     68                 printf("0
    ");
     69                 continue; 
     70             }
     71             if(l==1)
     72             {
     73                 printf("%lld
    ",2%mod);
     74                 continue;
     75             }
     76             if(l==2)
     77             {
     78                 printf("%lld
    ",4%mod);
     79                 continue;
     80             }
     81             if(l==3)
     82             {
     83                 printf("%lld
    ",6%mod);
     84                 continue;
     85             } 
     86             if(l==4)
     87             {
     88                 printf("%lld
    ",9%mod);
     89                 continue;
     90             } 
     91         }
     92     node res=pow_mod(a,b,l-4);
     93         int ans=0;  
     94       for(int i=0;i<4;i++)
     95       {
     96           ans+=f[3-i]*res.m[0][i]%mod;
     97       }
     98       printf("%lld
    ",ans%mod);
     99     }
    100 }
  • 相关阅读:
    c语言数组指针
    (4)activiti工作流引擎之uel表达式
    (3)activiti流程的挂起和激活
    (2)java程序走一遍工作流activiti
    (1)activiti认识以及数据库和插件配置
    linux 下路由配置
    lvs-dr+keepalived
    LVS-DR 配置测试
    简单认识TCP/IP协议
    mysql 主从同步-读写分离
  • 原文地址:https://www.cnblogs.com/1013star/p/9508323.html
Copyright © 2011-2022 走看看