hdu 4382 模拟 矩阵连乘 高精度

来源:互联网 发布:树的遍历递归算法 编辑:程序博客网 时间:2024/05/18 21:49

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4382

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

N<=10^100。

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

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

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

构造矩阵也不难,就是if else写个半天,可以看这里

最后需要模拟高精度除法,即一个高精度的数除以一个整数

if else 写的累shi 了尴尬

#include<cstdio>#include<cstring>#include<vector>#include<map>#include<algorithm>using namespace std;typedef __int64 lld;const int mod = 1000000007;const int maxn = 3;int n,m;int V;int bit[110];struct Matrix{    lld a[maxn][maxn];void init0(){memset(a,0,sizeof(a));}    void init1()    {        for(int i=0;i<maxn;i++)        {            for(int j=0;j<maxn;j++)            {                a[i][j]=(i==j);            }        }    }void print(){puts("***************");for(int i=0;i<3;i++){for(int j=0;j<3;j++){printf("%I64d ",a[i][j]);}puts("");}}};Matrix matrix_mul(Matrix a,Matrix b){    int i,j,k;    Matrix ans;    for(i=0;i<maxn;i++)    {        for(j=0;j<maxn;j++)        {            ans.a[i][j]=0;            for(k=0;k<maxn;k++)                ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;        }    }    return ans;}Matrix mult(Matrix a,int b){    Matrix ans;    ans.init1();    while(b)    {        if(b&1)            ans=matrix_mul(ans,a);        b>>=1;        a=matrix_mul(a,a);    }    return ans;}lld get_val(char *s){lld num=0;for(int i=0;s[i];i++)num=num*10+s[i]-'0';return num;}int main(){int t,ca=1;scanf("%d",&t);while(t--){scanf("%d",&V);char op[10],s1[10],s2[10];Matrix ms,tmp;ms.init1();//ms.print();while(scanf("%s",op),strcmp(op,"END")!=0){scanf("%s%s",s1,s2);tmp.init0();tmp.a[2][2]=1;if(op[0]=='S'){if(s1[1]=='1'){if(s2[0]=='C'){if(s2[1]=='1')tmp.a[0][0]=tmp.a[1][1]=1;else tmp.a[1][0]=tmp.a[1][1]=1;}else {lld num=get_val(s2);tmp.a[1][1]=1;tmp.a[2][0]=num;}}else {if(s2[0]=='C'){if(s2[1]=='1')tmp.a[0][0]=tmp.a[0][1]=1;else tmp.a[0][0]=tmp.a[1][1]=1;}else {lld num=get_val(s2);tmp.a[0][0]=1;tmp.a[2][1]=num;}}}else if(op[0]=='A'){if(s1[1]=='1'){if(s2[0]=='C'){if(s2[1]=='1')  tmp.a[0][0]=2,tmp.a[1][1]=1;else tmp.a[0][0]=tmp.a[1][0]=tmp.a[1][1]=1;}else {lld num=get_val(s2);tmp.a[0][0]=tmp.a[1][1]=1;tmp.a[2][0]=num;}}else {if(s2[0]=='C'){if(s2[1]=='1') tmp.a[0][0]=tmp.a[0][1]=tmp.a[1][1]=1;else tmp.a[0][0]=1,tmp.a[1][1]=2;}else{lld num=get_val(s2);tmp.a[0][0]=tmp.a[1][1]=1;tmp.a[2][1]=num;}}}else {lld num=get_val(s2);if(s1[1]=='1'){tmp.a[0][0]=num;tmp.a[1][1]=1;}else {    tmp.a[0][0]=1;tmp.a[1][1]=num;}}//tmp.print();//ms.print();ms=matrix_mul(ms,tmp);//ms.print();}Matrix mat=ms;int Q;char num[110];scanf("%d",&Q);printf("Case %d:\n",ca++);while(Q--){ms.init0();ms.a[0][0]=V,ms.a[0][2]=1;tmp=mat;scanf("%s",num);int len=strlen(num);for(int i=0;i<len;i++) bit[i]=num[len-1-i]-'0';while(len>0){if(bit[0]&1) ms=matrix_mul(ms,tmp);tmp=matrix_mul(tmp,tmp);int pre=0,sum;for(int i=len-1;i>=0;i--){sum=bit[i]+pre*10;bit[i]= (sum>>1);pre=sum&1;}while(len>0 && bit[len-1]==0) len--;}printf("%I64d\n",ms.a[0][1]);}}return 0;}