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

    题目描述

    小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题:

    给定正整数 N 和 M,要求计算 Concatenate (1 .. N) Mod M 的值,其中 Concatenate (1 ..N)是将所有正整数 1, 2, …, N 顺序连接起来得到的数。例如,N = 13, Concatenate (1 .. N)=12345678910111213.小C 想了大半天终于意识到这是一道不可能手算出来的题目,于是他只好向你求助,希望你能编写一个程序帮他解决这个问题。

    输入输出格式

    输入格式:

    从文件input.txt中读入数据,输入文件只有一行且为用空格隔开的两个正整数N和M,其中30%的数据满足1≤N≤1000000;100%的数据满足1≤N≤1018且1≤M≤109.

    输出格式:

    输出文件 output.txt 仅包含一个非负整数,表示 Concatenate (1 .. N) Mod M 的值。

    输入输出样例

     输入样例#1:
    13 13
     输出样例#1:
    4
    题解:
    这道题如果不是要考虑每一次乘上的数是10的几次方的话,那便是裸的矩阵快速幂,但是加上的话也无非就是多分几种情况讨论罢了。
    首先看递推式:f[i]=f[i-1]*10^k+i(可以看出只要对k讨论)
    然后写出两个矩阵:{{0,1,1},{0,0,0},{0,0,0}}和{{k%m,0,0},{1,1,0},{0,1,1}};
    快速幂即可。
    代码如下:(注意每次循环的分类讨论)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    using namespace std;
    typedef long long lol;
    lol n,m,now,pre;
    struct matrix
    {
        lol a[3][3];
        matrix(){for(int i=0;i<3;i++)for(int j=0;j<3;j++)a[i][j]=0;}
        matrix(lol b[3][3]){for(int i=0;i<3;i++)for(int j=0;j<3;j++)a[i][j]=b[i][j];}
        friend matrix operator * (const matrix a,const matrix b)
        {
            matrix ans;
            for(int i=0;i<3;i++)
                for(int j=0;j<3;j++)
                    for(int k=0;k<3;k++)
                    ans.a[i][j]=(ans.a[i][j]+(a.a[i][k]%m)*(b.a[k][j]%m)%m)%m;
            return ans;
        }
    }S,T;
    lol gi()
    {
        lol ans=0,f=1;
        char i=getchar();
        while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
        while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
        return ans*f;
    }
    int main()
    {
        lol i,j,k;
        n=gi();m=gi();
        lol s[3][3]={{0,1,1},{0,0,0},{0,0,0}};
        S=matrix(s);
        for(k=10;now<n;k*=10)
        {
            lol t[3][3]={{k%m,0,0},{1,1,0},{0,1,1}};
            T=matrix(t);
            pre=min(k-1,n)-now;
            while(pre)
            {
                if(pre&1)S=S*T;
                T=T*T;
                pre>>=1; 
            }
            now=min(k-1,n);
        }
        printf("%lld
    ",S.a[0][0]);
        return 0;
    }
     
  • 相关阅读:
    mininet和ryu控制器的连接
    Linux服务器(Ubuntu14.04)添加远程连接VNC Server
    KVM的前世今生
    Ubuntu下搭建ryu环境
    Ubuntu下搭建Mininet环境
    手机蓝牙
    常见的js算法面试题收集,es6实现
    前端笔试题面试题记录(上)
    关于js中onclick字符串传参问题(html="")
    Angular $scope和$rootScope事件机制之$emit、$broadcast和$on
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/7214691.html
Copyright © 2011-2022 走看看