矩阵基础1005 HDU 4686

来源:互联网 发布:sql 逐行累加 编辑:程序博客网 时间:2024/05/29 12:39

题意:
求sigma(ai*bi)|0<=i<=n-1
a(i)=a(i-1)*Ax+Ay
b(i)=b(i-1)*Bx+By
思路:
a(i)*b(i)=(a(i-1)*b(i-1)*Ax*Bx)+(a(i-1)*Ax*By)+(b(i-1)*Bx*Ay)+Ay*By
然后构造矩阵就好了
矩阵A
a(i-1),b(i-1),a(i-1)*b(i-1),1,Sum
矩阵B
Ax 0 AxBy 0 AxBy
0 Bx BxAy 0 BxAy
0 0 AxBx 0 AxBx
Ay By AyBy 1 AyBy
0 0 0 0 1

#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 = 100005;const int inf=(1<<28)-1;#define Matrix_Size 6const LL MOD = 1e9+7;int Size;struct Matrix{    LL 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");        }    }    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 main(){    Size=5;    LL n;    while(~scanf("%lld",&n))    {        LL A0,Ax,Ay,B0,Bx,By;        scanf("%lld%lld%lld",&A0,&Ax,&Ay);        scanf("%lld%lld%lld",&B0,&Bx,&By);        Matrix A,B;        A.clear();B.clear();        A.mat[0][0]=A0%MOD,A.mat[0][1]=B0%MOD;A.mat[0][2]=A0*B0%MOD,A.mat[0][3]=1;A.mat[0][4]=A0*B0%MOD;        B.mat[0][0]=Ax%MOD,B.mat[0][2]=Ax*By%MOD;B.mat[0][4]=Ax*By%MOD;        B.mat[1][2]=Ay*Bx%MOD,B.mat[1][1]=Bx%MOD,B.mat[1][4]=Ay*Bx%MOD;        B.mat[2][2]=Ax*Bx%MOD;B.mat[2][4]=Ax*Bx%MOD;        B.mat[3][0]=Ay%MOD,B.mat[3][1]=By%MOD,B.mat[3][2]=Ay*By%MOD;B.mat[3][3]=1;B.mat[3][4]=Ay*By%MOD;        B.mat[4][4]=1;        if(n==0)        {            printf("0\n");            continue;        }        if(n==1)        {            printf("%lld\n",A.mat[0][4]);            continue;        }        B=pow_M(B,n-1);        A=A*B;        //A.output();        printf("%lld\n",A.mat[0][4]);    }    return 0;}
0 0