zoukankan      html  css  js  c++  java
  • [HNOI2011] 数学作业

     

    转载请注明出处:

    http://www.cnblogs.com/hzoi-wangxh/p/7738627.html 

    [HNOI2011] 数学作业

    时间限制:1 s   内存限制:128 MB

    【题目描述】

    solution:

        用矩阵乘。

        在向后插入数时,相当于把原答案乘10的多少次方再加上这个数,所以我们可以导成矩阵。

        

            a矩阵                                  b矩阵

           

             ans                            10^j     1      0

      

              i                               0      1      1


              1                               0      0      1



        b矩阵第一行是把ans*10^j+i,第二行是让i加1,第三行是保持a[3]=1.


        由于10^j的j不同,所以我们应分层去求。


        然后我们就可以开心地矩阵快速幂了。


        注意时刻取模。


    附上代码:


     

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    long long ans,a[10],b[10][10],n,mod;
    void ksc(long long);
    void hucheng();
    void zicheng();
    int main()
    {
        scanf("%lld%lld",&n,&mod);
        long long x=10,y=10,z=9;
        a[2]=1;
        a[3]=1;
        while(x<=n)
        {
            memset(b,0,sizeof(b));
            b[1][1]=y;
            b[1][2]=b[2][2]=b[2][3]=b[3][3]=1;
            ksc(z);
            ans=a[1];
            x*=10;
            y*=10;
            y%=mod;
            z*=10;
        }
        memset(b,0,sizeof(b));
        b[1][1]=y;
        b[1][2]=b[2][2]=b[2][3]=b[3][3]=1;
        ksc(n-x/10+1);
        printf("%lld",a[1]);
        return 0;
    }
    void ksc(long long x)
    {
        while(x)
        {
            if((x&1)==1)
                hucheng();
            x=x>>1;
            zicheng();
        }
    }
    void hucheng()
    {
        long long c[7];
        memset(c,0,sizeof(c));
        for(long long  i=1;i<=3;i++)
            for(long long  j=1;j<=3;j++)
            {
                c[i]+=a[j]*b[i][j];
                c[i]%=mod;
            }
        for(long long  i=1;i<=3;i++)
            a[i]=c[i];
    }
    void zicheng()
    {
        long long c[7][7];
        memset(c,0,sizeof(c));
        for(long long  i=1;i<=3;i++)
            for(long long  j=1;j<=3;j++)
                for(long long  k=1;k<=3;k++)
                {
                    c[i][j]+=b[i][k]*b[k][j];
                    c[i][j]%=mod;
                }
        for(long long  i=1;i<=3;i++)
            for(long long  j=1;j<=3;j++)
                b[i][j]=c[i][j];
    }



  • 相关阅读:
    解决mybatis查询返回结果值串查
    MSSQL Export Excel
    Linux检测硬盘读取速度
    Linux修改用户密码
    Linux系统关闭防火墙端口
    Linux系统查看系统信息
    查找一个String中存储的多个数据
    编辑器vi命令
    去除一段文字最后一个符号
    替换Jar包中的一个文件 Replace a file in a JAR
  • 原文地址:https://www.cnblogs.com/hzoi-wangxh/p/7738627.html
Copyright © 2011-2022 走看看