bzoj 2326: [HNOI2011]数学作业

solution

矩阵:

f:                         a:

                                   10^k    0       0

ans    i    1    *                1       1       0

                                      1       1       1

分段乘,给a赋值10^k时记得给10^k%上mod,不然炸long long了

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #define ll long long
  5 #define chua(k) a[1][1]=p[k]%mod;a[1][2]=a[1][3]=a[2][3]=0;a[2][1]=a[2][2]=a[3][2]=a[3][3]=a[3][1]=1
  6 using namespace std;
  7 
  8 ll n;
  9 ll mod,weishu;
 10 ll f[5],a[5][5],temp[5][5];
 11 ll p[101],ci[101];
 12 
 13 void out11()
 14 {
 15     printf("\n");
 16     for(int i=1;i<=3;++i)
 17       printf("%lld ",f[i]);
 18     printf("\n");
 19     for(int i=1;i<=3;++i)
 20     {
 21         for(int j=1;j<=3;++j)
 22           printf("%lld ",a[i][j]);
 23         printf("\n");
 24     }
 25     printf("\n");
 26 }
 27 
 28 void work()
 29 {
 30     p[1]=10;ci[1]=9;
 31     for(int i=2;i<=18;++i)
 32     {
 33       p[i]=p[i-1]*10;
 34       ci[i]=ci[i-1]*10;
 35       //cout<<ci[i]<<endl;
 36     }
 37     
 38     for(ll i=n;i;i/=10)
 39       ++weishu;
 40     
 41     ci[weishu]=n-p[weishu-1]+1;
 42     
 43     //cout<<weishu<<endl;
 44     
 45     //for(int i=2;i<=18;++i)
 46     //  cout<<ci[i]<<endl;
 47     
 48     
 49     
 50     //cout<<weishu<<endl;
 51     
 52     f[1]=0;f[2]=0;f[3]=1;
 53     for(int l=1;l<=weishu;++l)
 54     {
 55         chua(l);
 56         
 57         while(ci[l])
 58         {
 59             //out11();
 60             
 61             if(ci[l]&1)
 62             {
 63                 for(int i=1;i<=3;++i)
 64                 {
 65                     temp[1][i]=0;
 66                     for(int k=1;k<=3;++k)
 67                         //temp[1][i]=(temp[1][i]+f[k]*a[k][i]);
 68                         temp[1][i]=(temp[1][i]+f[k]*a[k][i]%mod)%mod;
 69                 }
 70                 for(int i=1;i<=3;++i)
 71                   f[i]=temp[1][i];
 72             }
 73             
 74             for(int i=1;i<=3;++i)
 75               for(int j=1;j<=3;++j)
 76               {
 77                   temp[i][j]=0;
 78                   for(int k=1;k<=3;++k)
 79                       temp[i][j]=(temp[i][j]+a[i][k]*a[k][j]%mod)%mod;
 80                     //temp[i][j]=(temp[i][j]+a[i][k]*a[k][j]);
 81               }
 82             for(int i=1;i<=3;++i)
 83               for(int j=1;j<=3;++j)
 84                 a[i][j]=temp[i][j];
 85             
 86             ci[l]>>=1;
 87         }
 88     }
 89 }
 90 
 91 int main(){
 92     
 93 //    freopen("1.txt","r",stdin);
 94     //freopen("2.txt","w",stdout);
 95     
 96     scanf("%lld%lld",&n,&mod);
 97     work();
 98     printf("%lld",f[1]);
 99     return 0;
100 }
code
posted @ 2017-08-23 15:18  A_LEAF  阅读(105)  评论(0编辑  收藏  举报