zoukankan      html  css  js  c++  java
  • bzoj 3240 矩阵乘法+十进制快速幂

    首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b,

    那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)*b)^(n-1)*(a^(m-1))。

    然后用用十进制快速幂(因为输入用的是10进制,这样就避免了高精度除法)。

    第一次写十进制快速幂,大概的思想是维护当前位是1~9的要乘的矩阵,然后再通过这9个矩阵自己转移。

     1 /**************************************************************
     2     Problem: 3240
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:5352 ms
     7     Memory:2764 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <cctype>
    13 #include <algorithm>
    14 #define N 1000010
    15 #define Mod 1000000007
    16 using namespace std;
    17  
    18 typedef long long dnt;
    19 struct Matrix {
    20     dnt v[2][2];
    21     void make_unit() {
    22         for( int i=0; i<2; i++ )
    23             for( int j=0; j<2; j++ )
    24                 v[i][j] = (i==j);
    25     }
    26     inline const dnt* operator[]( int i ) const { return v[i]; }
    27     Matrix(){}
    28     Matrix( int aa, int ab, int ba, int bb ) {
    29         v[0][0] = aa, v[0][1] = ab, v[1][0] = ba, v[1][1] = bb;
    30     }
    31     Matrix operator*( const Matrix &b ) const {
    32         const Matrix &a = *this;
    33         return Matrix( 1, (b[0][1]+a[0][1]*b[1][1])%Mod,
    34                        0, a[1][1]*b[1][1]%Mod );
    35     }
    36     Matrix operator^( const char *b ) const {
    37         Matrix rt, q[10];
    38  
    39         q[1] = *this;
    40         for( int i=2; i<=9; i++ )
    41             q[i] = q[i-1]*q[1];
    42  
    43         rt.make_unit();
    44         for( int i=0; b[i]; i++ ) {
    45             if( b[i]-'0' ) rt = rt*q[b[i]-'0'];
    46             q[1] = q[1]*q[9];
    47             for( int j=2; j<=9; j++ )
    48                 q[j] = q[j-1]*q[1];
    49         }
    50         return rt;
    51     }
    52 };
    53  
    54 char sn[N], sm[N];
    55 int ln, lm;
    56 int a, b, c, d;
    57 Matrix ma, mb, ans;
    58  
    59 void subone( char s[] ) {
    60     int i = 0;
    61     s[i]--;
    62     while( s[i]<'0' ) {
    63         s[i] += 10;
    64         s[i+1]--;
    65         i++;
    66     }
    67 }
    68 int main() {
    69     scanf( "%s%s%d%d%d%d", sn, sm, &a, &b, &c, &d );
    70     ln = strlen(sn), lm = strlen(sm);
    71     reverse( sn, sn+ln );
    72     reverse( sm, sm+lm );
    73     subone(sn), subone(sm);
    74     ma = Matrix(1,b,0,a)^sm;
    75     mb = Matrix(1,d,0,c);
    76     ans = ((ma*mb)^sn)*ma;
    77     printf( "%lld
    ", (ans[0][1]+ans[1][1]) % Mod );
    78 }
    View Code
  • 相关阅读:
    【Flutter 实战】1.20版本更新及新增组件
    【Flutter 实战】各种各样形状的组件
    【Flutter 实战】全局点击空白处隐藏键盘
    Flutter —布局系统概述
    【Flutter 实战】17篇动画系列文章带你走进自定义动画
    lvs负载简介,原理,常见使用案例及Keepalived高可用
    02 . MongoDB复制集,分片集,备份与恢复
    Go之Casbin简介,安装,模型,存储,函数
    govendor包管理及Go项目热加载
    教你三招快速文件批量重命名方法
  • 原文地址:https://www.cnblogs.com/idy002/p/4528623.html
Copyright © 2011-2022 走看看