您的位置:首页 > 其它

[矩阵快速幂] hdu 4990 Reading comprehension

2014-09-25 16:28 274 查看
题意:

初始值为零,后面奇数项成二加一,偶数项乘二。

思路:

其实区别就在于这个加一。

就是构造一个-1每次相成,然后1-1+1就ok了。

就是

| -1 1 0 |

| -1 1 0 | * | 0 1 1 | = | 1 0 1 |

| 0 0 2 |

依次类推就好了。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
struct matrix
{
    __int64 mat[4][4];
};
matrix matmul(matrix a,matrix b,int n,int m)
{
    int i,j,k;
    matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            for(k=0; k<n; k++)
            {
                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
                c.mat[i][j]%=m;
            }

        }
    }
    return c;
}
matrix matpow(matrix a,int k,int n,int m)
{
    matrix b;
    int i;
    memset(b.mat,0,sizeof(b.mat));
    for(i=0; i<n; i++) b.mat[i][i]=1;
    while(k)
    {
        if(k&1) b=matmul(a,b,n,m);
        a=matmul(a,a,n,m);
        k>>=1;
    }
    return b;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=-1)
    {
        matrix a,b,ans;
        memset(a.mat,0,sizeof(a.mat));
        memset(b.mat,0,sizeof(b.mat));
        a.mat[0][0]=-1;
        a.mat[0][1]=1;
        b.mat[0][0]=-1;
        b.mat[0][1]=1;
        b.mat[1][1]=1;
        b.mat[1][2]=1;
        b.mat[2][2]=2;
        ans=matmul(a,matpow(b,n,3,m),3,m);
        printf("%I64d\n",(ans.mat[0][2]+m)%m);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: