zoukankan      html  css  js  c++  java
  • poj 3233 Matrix Power Series 矩阵 快速幂 两次二分

    题目地址: http://poj.org/problem?id=3233

    思想: 1模仿快速模幂法 ; 给矩阵写一个快幂

                 2 但是k太大 直接求和还是会tle  这个很像等比数列求和  但是可以递归用二分求,理论基础如下 :

                    求和二分:A+A^2+A...+A^(2k+1)=   A+A^2+...+A^k+A^(k+1)+A^(k+1)*(A+A^2+...+A^k).

                3  矩阵用结构体存储很好用呀  

                   之前 用int **存好像容易超内存 或者时间效率不高 

                4递归函数设计时,把调用递归的放在前面,这样实现自动回溯,而且不会爆栈

                5 用g++提交会runtime error  c++ ac  ,坑爹  搞了一晚上 

    #include<iostream>
    #include<cstdlib>
    #define maxn 101
    using namespace std;
    
    int n;
    int M;
    
    typedef
    struct
    {
       int  m[maxn][maxn];
    
    }matrix;
    
    
    matrix per;
    matrix a;
    void init()
    {
       for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
         {
    
            cin>>a.m[i][j];
            a.m[i][j]%=M;
    
            per.m[i][j]=(i==j);
         }
    }
    matrix multi(matrix a,matrix b)
    {
       matrix ans;
    
       for(int i=0;i<n;i++)
         for(int j=0;j<n;j++)
            {
                 ans.m[i][j]=0;
                for(int k=0;k<n;k++)
                   ans.m[i][j]+=(a.m[i][k]*b.m[k][j])%M;
                     ans.m[i][j]%=M;
    
            }
    
      return ans;
    }
    
    matrix quick_mod(int b)
    {
       matrix ans=per;
       matrix aa=a;
       while(b)
       {
         if(b&1)
         {
            ans=multi(ans,aa);
            b--;
         }
         b>>=1;
         aa=multi(aa,aa);
       }
    
       return ans;
    }
    
    matrix add(matrix a,matrix b)
    {
    
      matrix ans;
      for(int i=0;i<n;i++)
         for(int j=0;j<n;j++)
          {
            ans.m[i][j]=(a.m[i][j]+b.m[i][j])%M;
    
    //        ans.m[i][j]=a.m[i][j]+b.m[i][j];
    //        ans.m[i][j]%=M;
          }
       return ans;
    }
    
    matrix sum(int n)
    {
       if(n==1)  return a;
        matrix temp,b;
        temp = sum(n/2);
        if(n&1)
       {
         matrix b=quick_mod(n/2+1);
         matrix ans=multi(temp,b);
         ans=add(ans,temp);
         ans=add(ans,b);
    
         return ans;
    
       }
       else
       {
           matrix b=quick_mod(n/2);
           matrix  ans=temp;
           ans=multi(ans,b);
           ans=add(ans,temp);
           return ans;
    
       }
    // 或者这种写法
    //   if(n&1)
    //   {
    //       b=quick_mod(n/2+1);
    //       temp=add(temp,multi(temp,b));
    //       temp=add(temp,b);
    //
    //
    //   }
    //   else
    //   {
    //      b=quick_mod(n/2);
    //      temp=add(temp,multi(temp,b));
    //
    //   }
    //   return temp;
    
    }
    int main()
    {
    
    
       int k;
       cin>>n>>k>>M;
    
       init();
    
       matrix ans;
       ans=sum(k);
    
      for(int i=0;i<n;i++)
        {
          for(int j=0;j<n-1;j++)
           cout<<ans.m[i][j]<<" ";
           cout<<ans.m[i][n-1]<<endl;
        }
    
    
    }
    





  • 相关阅读:
    my34_脚本冥等添加自动任务-mysql监控部署
    zabbix4.2 安装
    面试题12:字符串无重复子串的最大长度
    面试题11:二叉树的非递归前、中、后、层级遍历
    面试题10:二叉树的最大路径和
    面试题9:数组堆化、堆的插入、堆的删除、堆排序
    面试题8:无序数组的最大差值
    面试题7:判断链表是否有环,返回环的入口点
    面试题6:二叉树最近公共节点(LCA)《leetcode236》
    面试题6:二叉树转单链表
  • 原文地址:https://www.cnblogs.com/814jingqi/p/3217951.html
Copyright © 2011-2022 走看看