poj 3233 --- Matrix Power Series (二分,矩阵)

原创 2012年03月22日 18:40:59


Matrix Power Series
Time Limit: 3000MS   Memory Limit: 131072K
Total 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 4
0 1
1 1

Sample Output

1 2
2 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}

A  可用二分迭代求出


因此,只要求出 上面的三部分就可以求出 S

//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,即初始化的矩阵不是单位矩阵I
		for(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^k
		tmp+= 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 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。k     这道题两次二分,相当...

poj 3233Matrix Power Series(矩阵快速幂 二分求和 求累乘的和)

Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 20...

poj 3233 Matrix Power Series(矩阵乘法·二分等比数列)

题目:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 13107...

POJ 3233 Matrix Power Series (矩阵快速幂+二分)

POJ 3233 Matrix Power Series (矩阵快速幂+二分)

POJ3233 - Matrix Power Series - 二分矩阵快速幂

#include #include int n,m; struct JZ { long long jz[50][50]; }s,map; JZ add(JZ a,JZ b) { JZ ans; ...
  • wsxsd94
  • wsxsd94
  • 2014年07月29日 15:53
  • 329

poj 3233 Matrix Power Series(矩阵二分,快速幂)

Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15...
  • caduca
  • caduca
  • 2014年10月28日 09:51
  • 597

POJ 3233 Matrix Power Series(矩阵的快速幂)

Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 17...

POJ 3233 Matrix Power Series (矩阵快速幂)

大致题意:简单题意就不解释了。    不过可以建议大家可以先做POJ 3070,先学会快速幂的基本思想。 没有做过的可以查看我的博客:点击打开链接 然后我们已经会使用矩阵快速幂求解A^k,则如何...

【POJ 3233】Matrix Power Series(矩阵快速幂)

既然难忘记,不如就让时光与回忆彼此相安

204_矩阵乘幂多项式 Matrix power series (POJ 3233)

给定一个nXn的矩阵A 和正整数k,m。如果  S=A+A^2+A^3+.........A^k, 求个元素对吗取余数后的结果。 同样,根据矩阵递推出关于k的式子,用乘幂的方法解决。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 3233 --- Matrix Power Series (二分,矩阵)
举报原因:
原因补充:

(最多只允许输入30个字)