• POJ 3233 Matrix Power Series(矩阵高速功率+二分法)


    职务地址:POJ 3233

    题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是相应位置分别相加)。输出的数据mod m。

    k<=10^9。
        这道题两次二分,相当经典。首先我们知道,A^i能够二分求出。

    然后我们须要对整个题目的数据规模k进行二分。比方,当k=6时,有:
        A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3)
        应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3。就可以得到原问题的答案。

    代码例如以下:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdlib.h>
    #include <math.h>
    #include <ctype.h>
    #include <queue>
    #include <map>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    int mod;
    int n;
    struct matrix
    {
        int ma[40][40];
    }init, res;
    matrix Mult(matrix x, matrix y)
    {
        int i, j, k;
        matrix tmp;
        memset(tmp.ma,0,sizeof(tmp.ma));
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                for(k=0;k<n;k++)
                {
                    tmp.ma[i][j]=(tmp.ma[i][j]+x.ma[i][k]*y.ma[k][j])%mod;
                }
            }
        }
        return tmp;
    }
    matrix Pow(matrix x, int k)
    {
        matrix tmp;
        int i, j;
        memset(tmp.ma,0,sizeof(tmp.ma));
        for(i=0;i<n;i++) tmp.ma[i][i]=1;
        while(k)
        {
            if(k&1) tmp=Mult(tmp,x);
            x=Mult(x,x);
            k>>=1;
        }
        return tmp;
    }
    matrix add(matrix x, matrix y)
    {
        int i, j;
        matrix tmp;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                tmp.ma[i][j]=(x.ma[i][j]+y.ma[i][j])%mod;
            }
        }
        return tmp;
    }
    matrix sum(matrix x, int k)
    {
        matrix tmp, y;
        if(k==1) return x;
        tmp=sum(x,k/2);
        if(k&1)
        {
            y=Pow(x,k/2+1);
            tmp=add(Mult(y,tmp),tmp);
            return add(tmp,y);
        }
        else
        {
            y=Pow(x,k/2);
            return add(Mult(y,tmp),tmp);
        }
    }
    int main()
    {
        int k, m, x, i, j;
        scanf("%d%d%d",&n,&k,&mod);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%d",&x);
                init.ma[i][j]=x%mod;
            }
        }
        res=sum(init, k);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                printf("%d",res.ma[i][j]);
                if(j!=n-1) printf(" ");
            }
            puts("");
        }
        return 0;
    }
    



    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    前台ajax传数组,后台java接收
    CSS揭秘—打字动效(四)
    通过四个问题了解HTTP协议基础
    Fiddler抓包工具怎么设置HTTPS抓包
    固定定位导致$(window).scrollTop();获取滚动后到顶部距离总是为0
    git bash 使用自带 curl 命令出现乱码解决方法
    移动端布局方案—vw+rem
    Windows安装Nginx需要注意的地方
    orientation属性(判断是否为横竖屏)
    js之瀑布流的实现
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4723707.html
Copyright © 2020-2023  润新知