• POJ3233 Matrix Power Series


      原题传送:http://poj.org/problem?id=3233

      两个二分:二分 k ,二分矩阵。

      求Sn = A + A2 + A3 + … + Ak

      首先我们能矩阵二分快速幂计算出Ak,那么我们对S再进行二分:

      当k % 2 != 0则计算Ak+S(k-1),当k % 2 == 0时计算S(k/2) * (Ak/2 + E),这样就可以在log(k)的时间里算出Sk

      ps:这题有两个地方要注意,否则可能会TLE

      1. 用 unsigned int,不要 long long

      2. 取模运算效率很低,矩阵乘法单个元素最大值不是很大的情况下先算出来再取一次模更好。

    View Code 200ms左右
     1 #include <stdio.h>
     2 #include <string.h>
     3 const int maxn = 31;
     4 struct mat
     5 {
     6     unsigned m[maxn][maxn];
     7 }a, E;
     8 unsigned n, k, MOD;
     9 
    10 mat operator *(mat u, mat v)
    11 {
    12     mat c;
    13     memset(c.m, 0, sizeof c.m);
    14     for(int i = 0; i < n; i ++)
    15         for(int j = 0; j < n; j ++){
    16             for(int r = 0; r < n; r ++)
    17                 c.m[i][j] += u.m[i][r] * v.m[r][j]; 
    18             c.m[i][j] %= MOD;
    19         }
    20     return c;
    21 }
    22 
    23 mat operator +(mat u, mat v)
    24 {
    25     mat c;
    26     for(int i = 0; i < n; i ++)
    27         for(int j = 0; j < n; j ++)
    28             c.m[i][j] = (u.m[i][j] + v.m[i][j]) % MOD;
    29     return c;
    30 }
    31 
    32 mat cal(mat A, int x)
    33 {
    34     mat t = E;
    35     for(; x; x >>= 1, A = A * A)
    36         if(x & 1) t = t * A;
    37     return t;
    38 }
    39 
    40 mat sum(int x)
    41 {
    42     if(x == 1)
    43         return a;
    44     if(x & 1)
    45         return cal(a, x) + sum(x - 1);
    46     else
    47         return sum(x / 2) * (E + cal(a, x / 2));
    48     return a;
    49 }
    50 int main()
    51 {
    52     while(scanf("%d%d%d", &n, &k, &MOD) != EOF)
    53     {
    54         for(int i = 0; i < n; i ++)
    55         {
    56             for(int j = 0; j < n; j ++)
    57             {
    58                 scanf("%u", &a.m[i][j]);
    59                 a.m[i][j] %= MOD;
    60                 E.m[i][j] = (i == j);
    61             }
    62         }
    63         mat ans = sum(k);
    64         for(int i = 0; i < n; i ++)
    65         {
    66             for(int j = 0; j < n-1; j ++)
    67                 printf("%u ", ans.m[i][j]);
    68             printf("%u\n", ans.m[i][n - 1]);
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    WINCE6.0+S3C6410睡眠和唤醒的实现
    WINCE6.0+S3C6410的触摸屏驱动
    S3C6410的Bootloader的两个阶段BL1和BL2编译相关学习
    amix vim vimrc 3.6 [_vimrc x64 vim (WorkPlace)]配置
    异常的开销
    A C# Reading List by Eric Lippert (ZZ)
    SQL SERVER 2008中定时备份数据库任务的创建与删除
    ASP.NET26个常用性能优化方法
    如何使用四个语句来提高 SQL Server 的伸缩性
    Cookies揭秘 [Asp.Net, Javascript]
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2836389.html
Copyright © 2020-2023  润新知