July 2019 Training (shop)

P3216 [HNOI2011] math homework

... looked segments

Let k be the number of digits

1--9 ->k=1

10--99 ->k=2

100--999->k=3

So recursive formula

 

 F [n ] = F [. 1-n ] * ^ 10-n. 1 + K (K is the number of bits n)
 

 So matrix becomes:

10^k 0 0
1 1 0
1 1 1

 

 
 

However, the matrix becomes longer, how to do it, we can be handled separately, initial matrix f [ 0 ] => (0,0,1)

Enumeration from 1 digit up to the length (n) -1-bit, 10k matrix multiplication has 9 * 10k-1 times.

Finally, treatment length (n) bits, multiplied 10length (n) matrix of n-Σlength (n) k = 1 (9 * 10k-1) times.

 


 

Spend more than one hour to finish, pay a 40 ...

Adjust two hours only to find the definition of ull, scanf% d ................. became a hit in the dish

So from Dev opened the biggest mistakes in the warning ...


 

AC 码

#include<cstdio>

#include<cstring>
#include<algorithm> 
#define ull unsigned long long
using namespace std;

ull n,m,po[25],lim[25];
struct MAT 
{
    ull a[3][3]; 
    MAT() {memset(a,0,sizeof a);}
}tran,ans;

void pre() 
{
    tran.a[0][1]=1,tran.a[0][2]=1;
    tran.a[1][0]=0,tran.a[1][1]=1,tran.a[1][2]=1;
    tran.a[2][0]=0,tran.a[2][1]=0,tran.a[2][2]=1;
    po[0]=0,po[1]=1; 
    for (int i=2; i<=19; i++) 
    {
        po[i]= po [i- 1 ] * 10 ; 
    } 
    Paste [ 0 ] = 1 ; 
    for ( int i = 1 ; i <= 18 ; i ++ ) 
    { 
        paste [i] = paste [i- 1 ] * 10 ;     
    } 
    Paste [ 0 ] = 2 ; 
    ans.a [ 0 ] [ 0 ] = 1 , ans.a [ 1 ] [ 0 ] = 1 , ans.a [ 2 ] [ 0 ] = 1 ; 
}

MAT mul(MAT u,MAT v) 
{
    MAT w; 
    int i,j,k;
    for (i=0;i<3;i++)
         for (j=0;j<3;j++)
             for (k=0;k<3;k++)
                 (w.a[i][j]+=u.a[i][k]*v.a[k][j])%=m;
    return w;
}

MAT pow(MAT b,ull p) 
{
    if(p==1) return b;
    MAT t=pow(b,p/2); 
    t=mul(t,t);
    return p%2==0?t:mul(t,b);
}

int main() 
{
    scanf("%lld%lld",&n,&m),pre();
    for (int i=1; i<=18; i++) 
    {
        if (lim[i-1]<=n) 
        {
               tran.a[0][0]=po[i+1]%m;
                   if (i<18&&lim[i]-1<=n) ans=mul(pow(tran,lim[i]-lim[i-1]),ans);
              else if (lim[i]>n) ans=mul(pow(tran,n-lim[i-1]+1),ans);
        }
        else break;
    }
    printf("%lld\n",ans.a[0][0]);
    return 0;
}

2019-07-30 00:57:02


Code is still something not clear, write tomorrow

 

Guess you like

Origin www.cnblogs.com/plzplz/p/11267466.html