HDU 4382 矩阵乘法

来源:互联网 发布:mysql deadlock 解决 编辑:程序博客网 时间:2024/05/22 12:12

题意:给出ADD SET MUL 操作,问你循环N次(N为大数),c2的结果,对1e9+7取模。

把每个操作转化成矩阵,相乘后根据费马小定理矩阵高次幂取模就行了。

转化的过程我的答案真在后面所以把字符串先存起来倒着乘的,如果答案阵在前那么就正这乘就行了。

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX=3;const long long M=1000000007;typedef struct{    long long m[MAX][MAX];} Matrix;Matrix I= {1,0,0,           0,1,0,           0,0,1          };Matrix data= {1,0,0,              0,1,0,              0,0,1             };Matrix P= {1,0,0,           0,1,0,           0,0,1          };Matrix matrixmul(Matrix a,Matrix b) //矩阵乘法{    int i,j,k;    Matrix c;    for (i = 0 ; i < MAX; i++)        for (j = 0; j < MAX; j++)        {            c.m[i][j] = 0;            for (k=0; k<MAX; k++)                c.m[i][j]+=((a.m[i][k]%(M))*(b.m[k][j]%(M)))%(M);            c.m[i][j] %=M;        }    return c;}Matrix quickpow(long long n){    Matrix m = P, b = I;    while (n >= 1)    {        if (n & 1)            b = matrixmul(b,m);        n = n >> 1;        m = matrixmul(m,m);    }    return b;}int getnum(char *s){    int ans=0;    int len=strlen(s);    for(int i=0; i<len; i++)        ans=ans*10+s[i]-'0';    return ans;}long long getnum1(char *s){    long long ans=0;    int len=strlen(s);    for(int i=0; i<len; i++)    {        ans=ans*10+s[i]-'0';        if(ans>M-1)            ans%=(M-1);    }    return ans;}void display(Matrix a){    for(int i=0; i<3; i++)    {        for(int j=0; j<3; j++)        {            cout<<a.m[i][j]<<" ";        }        cout<<endl;    }}int main(){    int t,n,ca=0;    char d1[100][15],d2[100][15],d3[100][15],s1[15],s2[15],s3[15];    long long v;    scanf("%d",&t);    while(t--)    {        P=I;        scanf("%I64d",&v);        int num=0;        while(scanf("%s",d1[num]),d1[num][0]!='E')        {            scanf("%s%s",d2[num],d3[num]);            num++;        }        for(int i=num-1; i>=0; i--)        {            strcpy(s1,d1[i]);            strcpy(s2,d2[i]);            strcpy(s3,d3[i]);            data=I;            if(s1[0]=='A')            {                if(s2[0]==s3[0]&&s2[1]==s3[1])                {                    if(s2[1]=='1')                        data.m[0][0]=2;                    else                        data.m[1][1]=2;                }                else if(s3[0]>='0'&&s3[0]<='9')                {                    if(s2[1]=='1')                        data.m[0][2]=getnum(s3);                    else                        data.m[1][2]=getnum(s3);                }                else                {                    if(s2[1]=='2'&&s3[1]=='1')                        data.m[1][0]=1;                    else                        data.m[0][1]=1;                }            }            if(s1[0]=='S')            {                if(s2[0]==s3[0]&&s2[1]==s3[1])                    data=I;                else if(s2[0]==s3[0]&&s2[1]=='1'&&s3[1]=='2')                    data.m[0][0]=0,data.m[0][1]=1;                else if(s2[0]==s3[0]&&s2[1]=='2'&&s3[1]=='1')                    data.m[1][1]=0,data.m[1][0]=1;                else if(s2[1]=='1')                    data.m[0][0]=0,data.m[0][2]=getnum(s3);                else if(s2[1]=='2')                    data.m[1][1]=0,data.m[1][2]=getnum(s3);            }            if(s1[0]=='M')            {                if(s2[1]=='1')                    data.m[0][0]=getnum(s3);                else                    data.m[1][1]=getnum(s3);            }            //display(data);            P=matrixmul(P,data);        }        scanf("%d",&n);        printf("Case %d:\n",++ca);        while(n--)        {            char s4[105];            scanf("%s",s4);            long long w=getnum1(s4);            Matrix final=quickpow(w);            // display(final);            long long ans=((final.m[1][0]*v)%M+final.m[1][2])%M;            printf("%lld\n",ans);        }    }    return 0;}


原创粉丝点击