矩阵基础1003 HDU 4965
来源:互联网 发布:mac怎么查看隐藏文件夹 编辑:程序博客网 时间:2024/06/04 23:26
题意:
给一个n*k的A矩阵和k*n的B矩阵(k<=6,n<=1000)
求(A*B)^(n*n),对于该矩阵的每个元素MOD6的和
思路:
一般方法在求幂的时候肯定会TLE
这里我们考虑拆分(A*B)^(n*n)
->(A*B)(A*B)^(n*n-2)(A*B)
->A*(B*A)^(n-1)*B 矩阵满足结合律
然后这样就可把A*B的1000*1000矩阵转化成6*6的矩阵
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 1005;const int inf=(1<<28)-1;#define Matrix_Size 7const LL MOD = 6;int Size;struct Matrix{ int mat[Matrix_Size][Matrix_Size]; void clear() { memset(mat,0,sizeof(mat)); } void output() { for(int i = 0;i < Size;i++) { for(int j = 0;j < Size;j++) printf("%d ",mat[i][j]); printf("\n"); } printf("\n"); } Matrix operator *(const Matrix &b)const { Matrix ret; for(int i = 0;i < Size;i++) for(int j = 0;j < Size;j++) { ret.mat[i][j] = 0; for(int k = 0;k < Size;k++) { long long tmp = (long long)mat[i][k]*b.mat[k][j]%MOD; ret.mat[i][j] = (ret.mat[i][j]+tmp); if(ret.mat[i][j]>=MOD) ret.mat[i][j] -= MOD; if(ret.mat[i][j]<0)//注意是否需要MOD ret.mat[i][j] += MOD; } } return ret; }};Matrix pow_M(Matrix a,long long n){ Matrix ret; ret.clear(); for(int i = 0;i < Size;i++) ret.mat[i][i] = 1; Matrix tmp = a; while(n) { if(n&1)ret = ret*tmp; tmp = tmp*tmp; n>>=1; } return ret;}int A[maxn][7],B[7][maxn],At[maxn][7];int main(){ int n,k; while(~scanf("%d%d",&n,&k)&&!(n==0&&k==0)) { Size=k; for(int i=0;i<n;++i) for(int j=0;j<k;++j) scanf("%d",&A[i][j]); for(int i=0;i<k;++i) for(int j=0;j<n;++j) scanf("%d",&B[i][j]); Matrix C; C.clear(); for(int i=0;i<k;++i) for(int j=0;j<k;++j) { for(int s=0;s<n;++s) { C.mat[i][j]+=B[i][s]*A[s][j]; } } //C.output(); C=pow_M(C,n*n-1); //C.output(); memset(At,0,sizeof(At)); for(int i=0;i<n;++i) { for(int j=0;j<k;++j) { for(int s=0;s<k;++s) { At[i][j]=(At[i][j]+A[i][s]*C.mat[s][j])%MOD; } } } /*for(int i=0;i<n;++i) { for(int j=0;j<k;++j) printf("%lld ",At[i][j]); printf("\n"); } printf("\n");*/ LL Ans=0; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { LL tmp=0; for(int s=0;s<k;++s) { tmp=(tmp+At[i][s]*B[s][j])%MOD; } ///printf("%d ",tmp); Ans+=tmp; } //printf("\n"); } printf("%lld\n",Ans); } return 0;}/*题意:给一个n*k的A矩阵和k*n的B矩阵(k<=6,n<=1000)求(A*B)^(n*n),对于该矩阵的每个元素MOD6的和思路:一般方法在求幂的时候肯定会TLE这里我们考虑拆分(A*B)^(n*n) ->(A*B)*(A*B)^(n*n-2)*(A*B)->A*(B*A)^(n-1)*B 矩阵满足结合律然后这样就可把A*B的1000*1000矩阵转化成6*6的矩阵 */#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 1005;const int inf=(1<<28)-1;#define Matrix_Size 7const LL MOD = 6;int Size;struct Matrix{ int mat[Matrix_Size][Matrix_Size]; void clear() { memset(mat,0,sizeof(mat)); } void output() { for(int i = 0;i < Size;i++) { for(int j = 0;j < Size;j++) printf("%d ",mat[i][j]); printf("\n"); } printf("\n"); } Matrix operator *(const Matrix &b)const { Matrix ret; for(int i = 0;i < Size;i++) for(int j = 0;j < Size;j++) { ret.mat[i][j] = 0; for(int k = 0;k < Size;k++) { long long tmp = (long long)mat[i][k]*b.mat[k][j]%MOD; ret.mat[i][j] = (ret.mat[i][j]+tmp); if(ret.mat[i][j]>MOD) ret.mat[i][j] -= MOD; if(ret.mat[i][j]<0)//注意是否需要MOD ret.mat[i][j] += MOD; } } return ret; }};Matrix pow_M(Matrix a,long long n){ Matrix ret; ret.clear(); for(int i = 0;i < Size;i++) ret.mat[i][i] = 1; Matrix tmp = a; while(n) { if(n&1)ret = ret*tmp; tmp = tmp*tmp; n>>=1; } return ret;}int A[maxn][7],B[7][maxn],At[maxn][7];int main(){ int n,k; while(~scanf("%d%d",&n,&k)&&!(n==0&&k==0)) { Size=k; for(int i=0;i<n;++i) for(int j=0;j<k;++j) scanf("%d",&A[i][j]); for(int i=0;i<k;++i) for(int j=0;j<n;++j) scanf("%d",&B[i][j]); Matrix C; C.clear(); for(int i=0;i<k;++i) for(int j=0;j<k;++j) { for(int s=0;s<n;++s) { C.mat[i][j]+=B[i][s]*A[s][j]; } } //C.output(); C=pow_M(C,n*n-1); //C.output(); memset(At,0,sizeof(At)); for(int i=0;i<n;++i) { for(int j=0;j<k;++j) { for(int s=0;s<k;++s) { At[i][j]=(At[i][j]+A[i][s]*C.mat[s][j])%MOD; } } } /*for(int i=0;i<n;++i) { for(int j=0;j<k;++j) printf("%lld ",At[i][j]); printf("\n"); } printf("\n");*/ LL Ans=0; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { LL tmp=0; for(int s=0;s<k;++s) { tmp=(tmp+At[i][s]*B[s][j])%MOD; } ///printf("%d ",tmp); Ans+=tmp; } //printf("\n"); } printf("%lld\n",Ans); } return 0;}
0 0
- 矩阵基础1003 HDU 4965
- hdu 1575 矩阵基础题
- 矩阵基础1001 HDU 4990
- 矩阵基础1004 HDU 5015
- 矩阵基础1005 HDU 4686
- 矩阵基础1006 HDU 4549
- hdu 1575 Tr A 矩阵基础题
- hdu 1005 Number Sequence 矩阵基础题
- hdu 1005 构造矩阵基础题
- hdu 4965 矩阵快速幂
- hdu 4965(矩阵乘法 )
- hdu 4965 矩阵快速幂
- HDU 4965 (矩阵快速幂)
- hdu 1757 A Simple Math Problem 矩阵基础题
- HDU 1005 Number Sequence(基础矩阵快速幂)
- dp基础6--[HDU-2859] 最大对称矩阵
- 矩阵基础
- 矩阵基础
- 【Maven用户手册】Maven生命周期
- OpenGL,z值转深度值计算
- Python图表绘制:matplotlib绘图库入门
- mysql的安装和用户权限
- android studio 怎么引入签名文件
- 矩阵基础1003 HDU 4965
- Java学习之Iterator(迭代器)的一般用法 (多方整理)
- pdo事物回滚
- ArcGIS Engine 10.0 for.NET开发学习笔记(八)
- 【Maven用户手册】Maven生命周期
- 小话java多线程机制
- 矩阵基础1004 HDU 5015
- poj 3304 segments 计算几何
- web.xml加载顺序