HDU4382(特殊的矩阵连乘)

题目:Harry Potter and Cyber Sequence Generator


题意,有两个容器C1,C2,初始的时候C1中有一个数的值为V,给你K个操作,每次都重复这K个操作N遍,最后问你C2中的数是

     多少。N<=10^100。

1:循环操作的次数巨大,敏感的想到这是矩阵连乘的题目。

2:K个操作可以得出一个矩阵,N个K操作就是这个矩阵的N次方

3:最后再乘以初始矩阵即可

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long LL;

const LL MOD=1000000007;
const int N=3;

struct Matrix
{
    LL m[N][N];
};

Matrix per={1,0,0,0,1,0,0,0,1};

Matrix multi(Matrix a,Matrix b)
{
    Matrix c;
    int i,j,k;
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            c.m[i][j]=0;
            for(k=0;k<N;k++)
            {
                c.m[i][j]+=(a.m[i][k]%MOD*(b.m[k][j]%MOD))%MOD;
                c.m[i][j]%=MOD;
            }
        }
    }
    return c;
}

Matrix matrix_mod(Matrix a,LL k)
{
    Matrix ans=per,p=a;
    while(k)
    {
        if(k&1)
        {
            ans=multi(ans,p);
            k--;
        }
        k>>=1;
        p=multi(p,p);
    }
    return ans;
}

LL getNum(char *str)
{
    LL ans=0;
    int len=strlen(str);
    for(int i=0;i<len;i++)
        ans=ans*10+str[i]-'0';
    return ans;
}

int main()
{
    Matrix ans,tmp1;
    LL T,V,Q,cas=1;
    char str[105];
    char str1[105];
    char str2[105];
    char str3[105];
    cin>>T;
    while(T--)
    {
        cin>>V;
        ans=per;
        while(cin>>str1)
        {
            if(str1[0]=='E') break;
            cin>>str2>>str3;
            tmp1=per;
            if(str1[0]=='S')
            {
                if(strcmp(str2,"C1,")==0&&strcmp(str3,"C2")==0)
                {
                    tmp1.m[0][0]=0;
                    tmp1.m[1][0]=1;
                }
                else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C1")==0)
                {
                    tmp1.m[0][1]=1;
                    tmp1.m[1][1]=0;
                }
                else if(strcmp(str2,"C1,")==0&&strcmp(str3,"C1")!=0)
                {
                    tmp1.m[0][0]=0;
                    tmp1.m[2][0]=getNum(str3);
                }
                else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C2")!=0)
                {
                    tmp1.m[1][1]=0;
                    tmp1.m[2][1]=getNum(str3);
                }
            }
            if(str1[0]=='A')
            {
                if(strcmp(str2,"C1,")==0&&strcmp(str3,"C1")==0)
                    tmp1.m[0][0]=2;
                else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C2")==0)
                    tmp1.m[1][1]=2;
                else if(strcmp(str2,"C1,")==0&&strcmp(str3,"C2")==0)
                    tmp1.m[1][0]=1;
                else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C1")==0)
                    tmp1.m[0][1]=1;
                else if(strcmp(str2,"C1,")==0)
                    tmp1.m[2][0]=getNum(str3);
                else
                    tmp1.m[2][1]=getNum(str3);
            }
            if(str1[0]=='M')
            {
                if(strcmp(str2,"C1,")==0)
                    tmp1.m[0][0]=getNum(str3);
                else
                    tmp1.m[1][1]=getNum(str3);
            }
            ans=multi(ans,tmp1);
        }
        cin>>Q;
        cout<<"Case "<<cas++<<":"<<endl;
        while(Q--)
        {
            cin>>str;
            LL ret=0;
            int len=strlen(str);
            for(int i=0;i<len;i++)
            {
                ret=ret*10+str[i]-'0';
                ret%=(MOD-1);
            }
            Matrix final=matrix_mod(ans,ret);
            LL sum=(final.m[0][1]%MOD*(V%MOD)%MOD+final.m[2][1]%MOD)%MOD;
            cout<<sum<<endl;
        }
    }
    return 0;
}


你可能感兴趣的:(HDU4382(特殊的矩阵连乘))