zoukankan      html  css  js  c++  java
  • 连续幂求和 [原]

      

    方法一

    O(logn)是由于每次还要计算

    改进:

          

    方法二

      

      

     1 /*
    2 * n阶矩阵A, 求A+。。。+A^k, 结果模mod。
    3 *
    4 * 类比上式:(注意这里从A开始加(而不是1),故略有不同)
    5 * m = {{f1}, {x}}
    6 * m1 = {{1}, {0}}
    7 * m2 = {{x, 0}, {0, x}}
    8 *
    9 * mm = {{f(r)}, {x^r}}
    10 *
    11 * facor = {{1+x^(r/2), 0}, {0, x^(r/2)}}
    12 */
    13
    14
    15 #include <cstdio>
    16 #include <cstring>
    17 using namespace std;
    18
    19 const int maxn = 30 + 2;
    20
    21 int n, k, mod;
    22 int m[maxn*2][maxn],
    23 m1[maxn*2][maxn*2], m2[maxn*2][maxn],
    24 lastAns[maxn*2][maxn];
    25
    26 void getFactor(int a[][maxn], int ans[][maxn*2]){
    27 memset(ans, 0, sizeof(int)*maxn*2*maxn*2);
    28 for(int i=0; i<n; i++){
    29 for(int j=0; j<n; j++){
    30 ans[i][j] = ans[i+n][j+n] = a[n+i][j];
    31 }
    32 ans[i][i] = (ans[i][i] + 1) % mod;
    33 }
    34
    35 }
    36 void multiply(int a[][maxn*2], int b[][maxn], int ans[][maxn]){
    37 memset(ans, 0, sizeof(m));
    38 for(int i=0; i<2*n; i++)
    39 for(int j=0; j<n; j++)
    40 for(int t=0; t<2*n; t++){
    41 ans[i][j] =(ans[i][j]+ a[i][t] * b[t][j]) % mod;
    42 }
    43 }
    44 void add(int a[][maxn], int b[][maxn]){
    45 for(int i=0; i<2*n; i++)
    46 for(int j=0; j<n; j++)
    47 b[i][j] = (a[i][j] + b[i][j]) % mod;
    48 }
    49
    50
    51 void cal(int r, int mm[][maxn]){
    52 if(r==1){
    53 memcpy(mm, m, sizeof(m));
    54 return;
    55 }
    56 int tmpAns[maxn*2][maxn]={};
    57 int factor[maxn*2][maxn*2]={};
    58 if(r%2==0){
    59 cal(r/2, tmpAns);
    60 getFactor(tmpAns, factor);
    61 multiply(factor, tmpAns, mm);
    62 }
    63 else{
    64 cal(r-1, tmpAns);
    65 multiply(m1, tmpAns, mm);
    66 add(m2, mm);
    67 }
    68 }
    69
    70
    71 int main(){
    72 scanf("%d%d%d", &n, &k, &mod);
    73 for(int i=0; i<n; i++)
    74 for(int j=0; j<n; j++){
    75 scanf("%d", &m[i][j]);
    76 m[i][j] %= mod;
    77 m[n+i][j] = m[i][j];
    78 m2[i][j] = m1[i][j] = m1[n+i][n+j] = m[i][j];
    79 }
    80
    81 cal(k, lastAns);
    82
    83 for(int i=0; i<n; i++){
    84 for(int j=0; j<n; j++){
    85 printf("%d ", lastAns[i][j]%mod);
    86 }
    87 printf("\n");
    88 }
    89 }



  • 相关阅读:
    codeforce A. 2Char(水题,暴力)
    hdu 4704 Sum(组合,费马小定理,快速幂)
    light oj 1100
    hdu 4503 湫湫系列故事——植树节(组合概率)
    Codeforces Round #327 (Div. 1), problem: (A) Median Smoothing
    hdu-3833 YY's new problem(数组标记)
    hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)
    hdu 1431 素数回文(暴力打表,埃托色尼筛法)
    hdu 1430 (BFS 康托展开 或 map )
    hdu 1024 max sum plus plus
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2368828.html
Copyright © 2011-2022 走看看