矩阵模板hdu5015,UVA 10655,UVA 11149
来源:互联网 发布:易语言取中间文本源码 编辑:程序博客网 时间:2024/06/04 19:44
hdu5015
n是<=10的,可以想到点什么,,
构造矩阵mat[n+2][n+2]
发现mat*a是答案矩阵第1列
mat的m次方再乘a就是答案矩阵的第m列,取最下面的就行了
这板不错
#include<cstdio>#include<cstring>#include<iostream>using namespace std;typedef long long ll;const int P = 10000007;const int N=13;ll n,m;struct matrix{ ll a[N][N]; int row,col; matrix():row(N),col(N){ memset(a,0,sizeof(a)); } matrix(int x,int y):row(x),col(y){ memset(a,0,sizeof(a)); } ll* operator [] (int x){ return a[x]; } matrix operator * (matrix x){ matrix tmp ; for (int i=0;i<=n+1;i++) for (int j=0;j<=n+1;j++){ tmp[i][j]=0; for (int k=0;k<=n+1;k++) tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%P; } return tmp; } void operator *= (matrix x){ *this = *this * x; } matrix operator ^ (ll x){ matrix ret; for (int i=0;i<=n+1;i++)ret[i][i]=1; matrix tmp = *this; for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;} return ret; } void print(){ for (int i=0;i<=n+1;i++){ for (int j=0;j<=n+1;j++) printf("%d ",a[i][j]); puts(""); } }};matrix getMatrix(){ matrix mat; mat[0][0]=10; mat[0][n+1]=1; for (int i=1;i<=n;i++) for (int j=0;j<=i;j++)mat[i][j]=1; for (int i=0;i<=n;i++)mat[n+1][i]=0; mat[n+1][n+1]=1; return mat;}int main(){ //freopen("fuck.in","r",stdin); while (~scanf("%I64d%I64d",&n,&m)){ matrix a; for (int i=1;i<=n;i++)scanf("%I64d",&a[i][0]); a[0][0] = 233,a[n+1][0] = 3; matrix mat = getMatrix(); mat = (mat ^ m) * a; printf("%I64d\n",mat[n][0]%P); } return 0;}
UVA 10655
题解
题目大意:给出a+b的值和ab的值,求a^n+b^n的值。
题目分析:有种错误的方法是这样的:利用已知的两个方程联立,求解出a和b,进而求出答案。这种方法之所以错,是因为这种方法有局限性。联立之后会得到一个二元一次方程,只有当该方程有实数解确切的说是当某个数据满足该方程有实数解时,这种方法得到的结果才有可能正确。显然,题中数据不可能这么片面。正确的方法是这样的:
令a+b=A,ab=B,S(n)=an+bn。
则S(n)=an+bn=(a+b)(a^n-1+b^n-1)-a*b^n-1-a^n-1*b
=(a+b)(an-1+bn-1)-ab(an-2+bn-2)=A*S(n-1)-B*S(n-2) (n≥2)。
由此构造2x2的矩阵:
matrix[1][1]=A,matrix[1][2]=-B;
matrix[2][1]=1,matrix[2][2]=0;
n=1或n=0时,答案显然。
要注意:数据中可能会出现A=B=0的情况,此时a=b=0,所以不能简单的判定当A=B=0时就结束输入数据。
#include<cstdio>#include<cstring>#include<iostream>using namespace std;typedef long long ll;const int N=4;struct matrix{ ll a[N][N]; int row,col; matrix():row(N),col(N){ memset(a,0,sizeof(a)); } matrix(int x,int y):row(x),col(y){ memset(a,0,sizeof(a)); } ll* operator [] (int x){ return a[x]; } matrix operator * (matrix x){ matrix tmp ; for (int i=1;i<=2;i++) for (int j=1;j<=2;j++){ tmp[i][j]=0; for (int k=1;k<=2;k++) tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j]); } return tmp; } void operator *= (matrix x){ *this = *this * x; } matrix operator ^ (ll x){ matrix ret; for (int i=1;i<=2;i++)ret[i][i]=1; matrix tmp = *this; for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;} return ret; } void operator ^=(ll x){ *this = *this ^ x; } void print(){ for (int i=1;i<=2;i++){ for (int j=1;j<=2;j++) printf("%d ",a[i][j]); puts(""); } }};ll solve(ll a ,ll b ,ll n){ if (n==0) return 2; if (n==1) return a; if (a==0&&b==0)return 0; matrix tra,ans; tra[1][1]=a;tra[1][2]=-b; tra[2][1]=1;tra[2][2]=0; ans[1][1]=a; ans[2][1]=2; ans = (tra^n)*ans; return ans[2][1];}int main(){ //freopen("fuck.in","r",stdin); ll p,q,n; while (scanf("%lld%lld%lld",&p,&q,&n)==3){ printf("%lld\n",solve(p,q,n)); } return 0;}
UVA 11149
题解
题目大意:给一个n阶方阵,求A1+A2+A3+……Ak。
题目分析:令F(k)=A1+A2+A3+……Ak。当k为偶数时,F(k)=F(k/2)(E+Ak/2),k为奇数时,F(k)=F(k/2)(E+Ak/2)+Ak。证明这两条公式也很简单,把这两条公式展开就行了。根据公式,递归即可。
/* * UVA 11149 Power of Matrix * by cww97*/#include<cstdio>#include<cstring>#include<iostream>using namespace std;typedef long long ll;const int N=43;int n;struct matrix{ ll a[N][N]; int row,col; matrix():row(N),col(N){ memset(a,0,sizeof(a)); } matrix(int x,int y):row(x),col(y){ memset(a,0,sizeof(a)); } ll* operator [] (int x){ return a[x]; } matrix operator + (matrix x){ matrix tmp ; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++){ tmp[i][j]=(a[i][j]+x[i][j])%10; } return tmp; } void operator += (matrix x){ *this = *this + x; } matrix operator * (matrix x){ matrix tmp ; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++){ tmp[i][j]=0; for (int k=1;k<=n;k++) tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%10; } return tmp; } void operator *= (matrix x){ *this = *this * x; } matrix operator ^ (ll x){ matrix ret; for (int i=1;i<=n;i++)ret[i][i]=1; matrix tmp = *this; for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;} return ret; } void operator ^=(ll x){ *this = *this ^ x; } void print(){ for (int i=1;i<=n;i++){ for (int j=1;j<n;j++) printf("%d ",a[i][j]%10); printf("%d\n",a[i][n]%10); } puts(""); }}E,A;matrix f(int k){ if (k==1)return A; matrix tmp = f(k>>1)*((A^(k>>1)) +E); if (k&1)tmp +=(A^k); return tmp;}int main(){ //freopen("fuck.in","r",stdin); int k,x; while (scanf("%d%d",&n,&k)==2&&n){ for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ scanf("%d",&x); A[i][j]=x%10; } } for (int i=1;i<=n;i++)E[i][i]=1; A = f(k); A.print(); } return 0;}
- 矩阵模板hdu5015,UVA 10655,UVA 11149
- uva 11149(矩阵倍增)
- 矩阵基础1007 UVA 11149
- hdu5015(矩阵优化)
- hdu5015---233 Matrix(矩阵)
- 矩阵快速幂-HDU5015
- uva 10655 Contemplation! Algebra 矩阵快速幂
- UVA 10655 Contemplation! Algebra(矩阵乘法)
- UVA 10655 - Contemplation! Algebra(矩阵快速幂)
- uva 10655 - Contemplation! Algebra(矩阵快速幂)
- UVA-10655 Contemplation! Algebra (矩阵快速幂)
- UVA 10655 Contemplation! Algebra(构造矩阵)
- UVA 10655 Contemplation! Algebra(矩阵乘法)
- uva 10655 公式变形 矩阵快速幂
- UVA 11149 - Power of Matrix(矩阵倍增)
- uva 11149 - Power of Matrix(矩阵倍增)
- UVA 11149 Power of Matrix(矩阵+二分)
- UVA 11149 & POJ 3233 矩阵的幂
- php中多种方法删除字符串中间的空格
- 软件调试学习(1)——分段地址,线性地址,物理地址
- 一个输出内容不同引发的问题
- LIS学习总结
- C++泛型编程1——函数模板实例化,模板参数,重载及特化
- 矩阵模板hdu5015,UVA 10655,UVA 11149
- 51Nod-1414-冰雕
- php中序列化与反序列化
- FFT(快速傅里叶变换)算法学习笔记
- Maven工程管理要点
- Ionic简介和环境安装
- php --post中提交数组参数
- MySQL enum类型及在PHP中的使用
- HDU 5821 Ball 贪心+映射