zoukankan      html  css  js  c++  java
  • 2019年7月训练(肆)

    P3216 [HNOI2011]数学作业

    看了一眼...分段

    设k为数字的位数

    1--9 ->k=1

    10--99 ->k=2

    100--999->k=3

    所以递推式为

     f[n]=f[n-1]*10^k+n-1(k为n的位数)
     

     所以矩阵变为:

    10^k00
    1 1 0
    1 1 1
     
     

    但是,矩阵会变长,怎么做呢,我们可以分开处理,初始矩阵 f[0]=>(0,0,1)

    从1枚举位数,一直到length(n)−1位,一直乘10k的矩阵9∗10k−1次。

    最后处理length(n)位,乘以10length(n)矩阵n−∑length(n)k=1(9∗10k−1)次。

     


    花一个多小时写完,一交40...

    调了两小时才发现定义的ull,scanf里打成了%d.................菜

    所以从此打开了Dev里的最大错误警示...


    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;
        }
        lim[0]=1; 
        for (int i=1; i<=18; i++)
        {
            lim[i]=lim[i-1]*10;     
        } 
        lim[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
    ",ans.a[0][0]);
        return 0;
    }

    2019-07-30 00:57:02

     

  • 相关阅读:
    【洛谷 P1896】[SCOI2005]互不侵犯(状压dp)
    【洛谷 P4289】[HAOI2008]移动玩具(搜索)
    【洛谷 SP283】NAPTIME
    【洛谷 P4342】[IOI1998]Polygon(DP)
    【洛谷 SP2878】Knights of the Round Table(双联通分量)
    【洛谷 P4168】[Violet]蒲公英(分块)
    【洛谷 P4180】【模板】严格次小生成树[BJWC2010](倍增)
    数学总结
    个人码风
    【洛谷 P3304】[SDOI2013]直径(树的直径)
  • 原文地址:https://www.cnblogs.com/plzplz/p/11267466.html
Copyright © 2011-2022 走看看