zoukankan      html  css  js  c++  java
  • poj 3233 Matrix Power Series(矩阵二分,高速幂)

    Matrix Power Series
    Time Limit: 3000MS   Memory Limit: 131072K
    Total Submissions: 15739   Accepted: 6724

    Description

    Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

    Input

    The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.

    Output

    Output the elements of S modulo m in the same way as A is given.

    Sample Input

    2 2 4
    0 1
    1 1

    Sample Output

    1 2
    2 3


    当k为奇数时

    Sk = A + A2 + A3 + … + Ak  

        =(1+Ak/2)*(A + A2 + A3 + … + Ak/2  )+{Ak}

        =(1+Ak/2)*(Sk/2 )+{Ak}

    当k为偶数时

    Sk = A + A2 + A3 + … + Ak  

        =(1+Ak/2)*(A + A2 + A3 + … + Ak/2  )+{Ak}

        =(1+Ak/2)*(Sk/2 )

    就能够二分递归求Sk

    代码:

    //829ms
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m;
    struct matrix
    {
        int ma[50][50];
    } a;
    matrix multi(matrix x,matrix y)//矩阵相乘
    {
        matrix ans;
        memset(ans.ma,0,sizeof(ans.ma));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(x.ma[i][j])//稀疏矩阵优化
                    for(int k=1; k<=n; k++)
                    {
                        ans.ma[i][k]=(ans.ma[i][k]+x.ma[i][j]*y.ma[j][k])%m;
                    }
            }
        }
        return ans;
    }
    matrix add(matrix x,matrix y)//矩阵相加
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                x.ma[i][j]=(x.ma[i][j]+y.ma[i][j])%m;
        return x;
    }
    matrix pow(matrix a,int m)
    {
        matrix ans;
        for(int i=1; i<=n; i++) //单位矩阵
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    ans.ma[i][j]=1;
                else
                    ans.ma[i][j]=0;
            }
        }
        while(m)//矩阵高速幂
        {
            if(m&1)
            {
                ans=multi(ans,a);
            }
            a=multi(a,a);
            m=(m>>1);
        }
        return ans;
    }
    matrix solve(matrix x,int k)//递归求Sk
    {
        if(k==1)
            return x;
        matrix ans;
        for(int i=1; i<=n; i++) //单位矩阵
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    ans.ma[i][j]=1;
                else
                    ans.ma[i][j]=0;
            }
        }
        ans=add(ans,pow(x,k/2));
        ans=multi(ans,solve(x,k/2));
        if(k&1)
            ans=add(ans,pow(x,k));
        return ans;
    }
    int main()
    {
        int k;
        while(~scanf("%d%d%d",&n,&k,&m))
        {
            matrix ans,a;
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                    scanf("%d",&a.ma[i][j]);
            }
            ans=solve(a,k);
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<n; j++)
                    printf("%d ",ans.ma[i][j]);
                printf("%d
    ",ans.ma[i][n]);
            }
        }
        return 0;
    }
    




  • 相关阅读:
    Sqlserver中的触发器
    Memcache在.Net中的使用
    Sqlserver中的储存过程
    Ado.NET基础必备
    MVC项目报错 ”基础提供程序在 Open 上失败”
    【Darwin学习笔记】之获取系统处理器数量的方法
    Wireshark抓包工具--TCP数据包seq ack等解读
    TCP:WireShark分析,序列号Seq和确认号Ack
    【Darwin学习笔记】之TaskThread
    boost::asio::io_context类
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6808834.html
Copyright © 2011-2022 走看看