uva11149power of matrix二分

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87585#problem/B

题意:A+A^2+A^3+……+A^k,A为矩阵,首先输入A的介数n和次数k,再输入A,要求将结果输出。

思路:

当n为偶数时,

f(n)=f(n/2)+f(n/2)*A^(n/2)=f(n/2)(E+A^(n/2)),

当n为奇数时,

f(n)=f(n/2)+f(n/2)*A^(n/2)+A^n=f(n/2)(E+A^(n/2))+A^n。

(二分法)

一开始看到输出中说因为数据过大要输出最后一位数据,认为是数组的最后一个数,但是看例题又不是那样,后来看题解才明白是每个数组元素的最后一位。

在所有可以%10的地方%10。

#include<iostream>
using namespace std;
typedef long long ll;
struct Matrix
{
    ll v[41][41];
};
Matrix m;
Matrix k(int n)
{
    Matrix a;
    for(int i=0;i<n;i++)
    {   for(int j=0;j<n;j++)
        {
            a.v[i][j]=0;
        }
    }
    return a;
}//将给定介数的矩阵化为零矩阵
Matrix E(int n)
{
    Matrix a=k(n);
    for(int i=0;i<n;i++)
    {
        a.v[i][i]=1;
    }
    return a;
}//单位矩阵
Matrix sum(Matrix a,Matrix b,int n)
{
    Matrix c;
    for(int i=0;i<n;i++)
    {   for(int j=0;j<n;j++)
        {
            c.v[i][j]=a.v[i][j]+b.v[i][j];
            c.v[i][j]%=10;
        }
    }
    return c;
}//矩阵加法
Matrix mul(Matrix a,Matrix b,int n)
{
    Matrix c;
    for(int i=0;i<n;i++)
    {   for(int j=0;j<n;j++)
        {
            c.v[i][j]=0;
            for(int l=0;l<n;l++)
            {
                c.v[i][j]+=a.v[i][l]*b.v[l][j];
                c.v[i][j]%=10;
            }
        }
    }
    return c;
}//矩阵乘法
Matrix pow(Matrix a,int k,int n)
{
    if(k==1)return a;
    Matrix b=pow(a,k>>1,n);
    if(k%2)return mul(mul(b,b,n),m,n);
    else return mul(b,b,n);
}//矩阵快速幂
Matrix qpow(Matrix a,int k,int n)
{
    if(k==1)return a;
    Matrix b=qpow(a,k/2,n);
    Matrix c=sum(E(n),pow(a,k/2,n),n);
    if(k%2)return sum(mul(b,c,n),pow(a,k,n),n);
    else return mul(b,c,n);
}//矩阵二分法快速求和
void input(int n)
{
    for(int i=0;i<n;i++)
    {   for(int j=0;j<n;j++)
        {
            cin>>m.v[i][j];
            m.v[i][j]%=10;
        }
    }
}//输入A
void show(Matrix a,int n)
{
    for(int i=0;i<n;i++)
    {   for(int j=0;j<n;j++)
        {
            cout<<a.v[i][j];
            if(j==n-1)cout<<endl;
            else cout<<" ";
        }
    }
    cout<<endl;
}//输出结果
int main()
{
    int n,k;
    while(cin>>n>>k&&n)//当n是0时结束程序,案例中给出的是0 0,故while(cin>>n>>k&&n)
    {
        input(n);
        Matrix e=m;
        Matrix ans=qpow(e,k,n);
        show(ans,n);
    }
    return 0;
}

 

posted @ 2016-04-29 21:12  哲贤  阅读(247)  评论(0编辑  收藏  举报