poj 3233 --- Matrix Power Series (二分,矩阵)
来源:互联网 发布:广元广电网络宽带资费 编辑:程序博客网 时间:2024/05/22 16:53
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072KTotal Submissions: 9393 Accepted: 4018
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 40 11 1
Sample Output
1 22 3
Source
POJ Monthly--2007.06.03, Huang, Jinsong
Sk = A + A2 + A3 + … + Ak
=(1+Ak/2)*(A + A2 + A3 + … + Ak/2 )+{Ak}
=(1+Ak/2)*(Sk/2 )+{Ak}// k为偶数时无 {Ak}
Ak 可用二分迭代求出
因此,只要求出 上面的三部分就可以求出 Sk
//800MS#include <iostream>#include <cstdio>#include <cstring>using namespace std;int m,n,K;int a[30][30];class Matrix{public: int num[30][30]; Matrix(bool is=true)//初始化 { memset(num,0,sizeof(num));if(is)for(int i=0;i<n;i++)num[i][i]=1; } void print()//输出函数 { for(int i=0;i<n;++i) { printf("%d",num[i][0]); for(int j=1;j<n;++j) printf(" %d",num[i][j]); printf("\n"); } }//重载乘法运算 friend Matrix& operator *(const Matrix& max1,const Matrix& max2){Matrix tmp(false);//注意这里是false,即初始化的矩阵不是单位矩阵Ifor(int i=0;i<n;++i)for(int j=0;j<n;++j){for(int k=0;k<n;++k)tmp.num[i][j]+=(max1.num[i][k]*max2.num[k][j])%m; tmp.num[i][j]%=m;}return tmp;} //重载+=运算 Matrix& operator +=(const Matrix& max) { for(int i=0;i<n;++i) for(int j=0;j<n;++j) num[i][j]=(num[i][j]+max.num[i][j])%m;return *this;}}ans;Matrix mul(Matrix A,int k)//求A^K{if(k==1)return A;Matrix tmp ;while(k){if(k&1)tmp = tmp * A;k>>=1;A = A*A;}return tmp;}Matrix S(Matrix A,int k)//求 S[k]{if(k==1)return A;Matrix tmp ;tmp += mul(A,k>>1);//求 (I + A^(k/2) )tmp = tmp*S(A,k>>1);//求 (I + A^(k/2) )*S[k/2]if(k&1)//判断时候要加上 A^ktmp+= mul(A,k);//S[k] = (I+A^(k/2)) * S[k/2] + {A^k}return tmp;} int main(){int i,j,k; scanf("%d %d %d",&n,&K,&m); for( i=0;i<n;++i) for( j=0;j<n;++j) scanf("%d",&ans.num[i][j]);ans = S(ans,K);ans.print();return 0;}
效率更高的代码1:
//266MS#include <iostream>#include <cstdio>#include <cstring>using namespace std;int m,n,K;int a[30][30];class Matrix{ public: int num[61][61]; Matrix() { memset(num,0,sizeof(num)); } void print() { for(int i=0;i<n;++i) { printf("%d",num[i][0]); for(int j=1;j<n;++j) printf(" %d",num[i][j]); printf("\n"); } printf("\n"); } friend Matrix& operator *(Matrix max1,Matrix max2);};Matrix& operator *(Matrix max1,Matrix max2){ Matrix tmp; for(int i=0;i<2*n;++i) for(int j=0;j<2*n;++j) { for(int k=0;k<2*n;++k) tmp.num[i][j]+=(max1.num[i][k]*max2.num[k][j])%m; tmp.num[i][j]%=m; } return tmp;}int main(){ scanf("%d %d %d",&n,&K,&m); for(int i=0;i<n;++i) for(int j=0;j<n;++j) scanf("%d",&a[i][j]); Matrix b,c; for(int i=0;i<n;++i) for(int j=0;j<n;++j) c.num[i+n][j+n]=b.num[i][j+n]=a[i][j]; for(int k=0;k<2;++k) for(int i=0;i<n;++i) c.num[i+k*n][i]=1; while(K) { if(K&1) b=b*c; K>>=1; c=c*c; } b.print(); return 0;}
效率更高的代码2:
#include<cstdio>#include<cstring>using namespace std;int i,j,k,n,l,m,r;bool s[32];struct matrix{ int a[30][30]; void pr() { for(i=0; i<n;printf("%d/n",a[i++][j])) for(j=0;j<n-1;++j)printf("%d ",a[i][j]); } matrix& operator+=(const matrix&x) { for(int i=0; i<n; ++i) for(int j=0; j<n; ++j) if(x.a[i][j]) { a[i][j]+=x.a[i][j]; if(a[i][j]>=m)a[i][j]%=m; } return *this; } matrix& operator*=(const matrix&x) { matrix t; int i,j,k; for(i=0; i<n; ++i) for(j=0; j<n; ++j)t.a[i][j]=0; for(i=0; i<n; ++i) for(k=0; k<n; ++k) if(a[i][k]) for(j=0; j<n; ++j) { t.a[i][j]+=a[i][k]*x.a[k][j]; if(t.a[i][j]>=m)t.a[i][j]%=m; } return memcpy(a,t.a,sizeof(a)),*this; }} t,a,unit,ans,exp;int& fun(int &a){ return a;}int main(){ for(scanf("%d%d%d",&n,&l,&m),i=0; i<30; ++i)unit.a[i][i]=1; for(i=0; i<n; ++i) for(j=0; j<n; ++j) scanf("%d",a.a[i]+j); for(r=-1;l;l>>=1)s[++r]=l&1; for(ans=exp=a; --r>=0; exp*=exp,s[r]?exp*=a:exp) t=exp,s[r]?ans*=(t*=a)+=unit,ans+=(t=exp)*=a:ans*=t+=unit; ans.pr(); return 0;}
- poj 3233 --- Matrix Power Series (二分,矩阵)
- POJ 3233 Matrix Power Series (矩阵 + 二分)
- POJ 3233 Matrix Power Series(矩阵+二分)
- POJ 3233 Matrix Power Series (矩阵+二分+二分)
- POJ 3233 Matrix Power Series(二分 / 矩阵套矩阵)
- poj 3233 Matrix Power Series 矩阵 快速幂 两次二分
- POJ 3233 Matrix Power Series(矩阵快速幂+二分求和)
- POJ 3233 Matrix Power Series 矩阵快速幂+二分
- POJ 3233 Matrix Power Series 矩阵快速幂+二分
- POJ 3233 Matrix Power Series (矩阵快速幂 + 二分)
- POJ - 3233 Matrix Power Series (矩阵等比二分求和)
- POJ 3233 Matrix Power Series 二分+矩阵乘法
- POJ 3233 Matrix Power Series(矩阵快速幂+二分)
- poj 3233 Matrix Power Series(矩阵二分,快速幂)
- POJ 3233 Matrix Power Series --二分求矩阵等比数列和
- POJ 3233 Matrix Power Series (矩阵快速幂+二分)
- poj 3233 Matrix Power Series(矩阵乘法·二分等比数列)
- poj 3233 Matrix Power Series 矩阵快速幂or二分
- 如何除去HTML标签并保留文字
- 数据结构的C实现_顺序表
- 数据结构的C实现_单向链表
- 数据结构的C实现_双向循环链表
- 第五周实验报告(3)
- poj 3233 --- Matrix Power Series (二分,矩阵)
- ASP.NET Eval格式化汇总
- 关于java乱码的一些总结
- 循环链表的应用_约瑟夫环
- VS2010不能创建项目解决方法
- 使用CRichEditCtrl与正则实现XML高亮编辑器
- linux下批量创建目录
- 数据结构的C实现_顺序栈
- FLASH图片自动切换代码