zoukankan      html  css  js  c++  java
  • poj 3734 矩阵快速幂+YY

    题目原意:N个方块排成一列,每个方块可涂成红、蓝、绿、黄。问红方块和绿方块都是偶数的方案的个数。

    sol:找规律列递推式+矩阵快速幂

    设已经染完了i个方块将要染第i+1个方块。

    a[i]=1-i方块中,红、绿方块数量都是偶数的方案数

    b[i]=1-i方块中,红、绿方块数量一个是偶数一个是奇数的方案数(红even绿odd 或 红odd绿even)

    c[i]=1-i方块中,红、绿方块数量都是奇数的方案数

    可以得出递推公式:

    a[i+1]=2*a[i]+b[i]    

    b[i+1]=2*a[i]+2*b[i]+2*c[i]

    c[i+1]=b[i]+2*c[i]

    如何和矩阵结合起来呢?不妨把公式这样写一遍,

    a[i+1]=2*a[i]+1*b[i]+0*c[i]    

    b[i+1]=2*a[i]+2*b[i]+2*c[i]

    c[i+1]=0*a[i]+1*b[i]+2*c[i]

    然后可以YY出一个矩阵:

    因此,

    这样就可以用矩阵快速幂求解了。

     1 #include "iostream"
     2 #include "vector"
     3 #include "cstring"
     4 using namespace std;
     5 
     6 typedef unsigned long int ULL;
     7 typedef vector<ULL> vec;
     8 typedef vector<vec> mat;
     9 const ULL P=10007;
    10 int n,m;
    11 
    12 mat mul(mat &A,mat &B)      //return A*B
    13 {
    14     mat C(A.size(),vec(B[0].size()));
    15     for (int i=0;i<(int)A.size();i++)
    16     {
    17         for (int k=0;k<(int)B.size();k++)
    18         {
    19             for (int j=0;j<(int)B[0].size();j++)
    20             {
    21                 C[i][j]=(C[i][j]+A[i][k]*B[k][j])%P;
    22             }
    23         }
    24     }
    25     return C;
    26 }
    27 
    28 mat m_pow(mat A,int m)      //return A^m
    29 {
    30     mat B(A.size(),vec(A.size()));
    31     for (int i=0;i<(int)A.size();i++)
    32         B[i][i]=1;
    33     while (m>0)
    34     {
    35         if (m&1)    B=mul(B,A);
    36         A=mul(A,A);
    37         m>>=1;
    38     }
    39     return B;
    40 }
    41 
    42 int main()
    43 {
    44     int T,N;
    45     cin>>T;
    46     while (T--)
    47     {
    48         cin>>N;
    49         mat A(3,vec(3));
    50         A[0][0]=2;  A[0][1]=1;  A[0][2]=0;
    51         A[1][0]=2;  A[1][1]=2;  A[1][2]=2;
    52         A[2][0]=0;  A[2][1]=1;  A[2][2]=2;
    53 
    54         A=m_pow(A,N);
    55 
    56         cout<<A[0][0]<<endl;
    57     }
    58     return 0;
    59 }
    60 
    61 /*
    62 int main()
    63 {
    64     int T;
    65     cin>>T;
    66     while (T--)
    67     {
    68         cin>>n>>m;
    69         mat A(n,vec(n));
    70 
    71         for (int i=0;i<n;i++)
    72             for (int j=0;j<n;j++)
    73                 cin>>A[i][j];
    74 
    75         A=m_pow(A,m);
    76 
    77         ULL ans=0;
    78         for (int i=0;i<n;i++)
    79         {
    80             ans+=A[i][i];
    81             ans=ans%P;
    82         }
    83         cout<<ans<<endl;
    84     }
    85     return 0;
    86 }
    87 */
    View Code
  • 相关阅读:
    USB子系统gadget analyse
    关于嵌入式的学习和职业发展
    编译JNI动态库so
    Linux串口编程
    i2c_get_clientdata和to_i2c_client 的使用获取平台设备
    Kbuild 编译系统分析
    解决QPST 出现的 "服务器正在运行" 的 下载错误.
    Msm 高通平台配置记录之一
    USB Skeleton driver 分析记录
    网站应用数据库相关 过滤类
  • 原文地址:https://www.cnblogs.com/pdev/p/4063194.html
Copyright © 2011-2022 走看看