zoukankan      html  css  js  c++  java
  • 数学作业(codevs 2314)

    题目描述 Description

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

    输入描述 Input Description

    只有一行 为用空格隔开的两个正整数 N 和 M

    输出描述 Output Description

    仅包含一个非负整数,表示 Concatenate (1 .. N ) Mod M 的值

    样例输入 Sample Input

    13 13

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

    其中 30%的数据满足1≤ N ≤1000000;100%的数据满足1≤ N ≤1018且1≤ M ≤109

    /*
        矩阵乘法
        按位进行计算,公式很好推。
        矩阵乘法写得少,导致代码特别难看。
    */
    #include<cstdio>
    #include<iostream>
    #define lon long long
    using namespace std;
    lon A[4][4],B[4][4],n,mod,ans;
    void mul(lon a[4][4],lon b[4][4],lon c[4][4]){
        lon tmp[4][4]={0};
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                for(int k=1;k<=3;k++)
                    tmp[i][j]+=(a[i][k]*b[k][j])%mod,tmp[i][j]%=mod;
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                c[i][j]=tmp[i][j];
    }
    void mi(lon a[4][4],lon b){
        lon base[4][4]={0},r[4][4]={0};
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                base[i][j]=a[i][j];
        for(int i=1;i<=3;i++) r[i][i]=1;
        while(b){
            if(b&1) mul(base,r,r);
            mul(base,base,base);
            b>>=1;
        }
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                a[i][j]=r[i][j];
    }
    lon pow10(int x){
        lon ans=1;
        for(int i=1;i<=x;i++) ans*=10;
        return ans;
    }
    void init(){
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=ans*10+i,ans%=mod;
        cout<<ans;
    }
    int main(){
        cin>>n>>mod;
        if(n<10) {init();return 0;}
        ans=123456789;
        for(int i=2;i<=18;i++){
            A[1][1]=ans;A[1][2]=pow10(i-1)%mod;A[1][3]=1;
            A[2][1]=A[2][2]=A[2][3]=0;
            A[3][1]=A[3][2]=A[3][3]=0;
            B[1][1]=pow10(i)%mod;B[1][2]=0;B[1][3]=0;
            B[2][1]=1;B[2][2]=1;B[2][3]=0;
            B[3][1]=0;B[3][2]=1;B[3][3]=1;
            lon ci=min(pow10(i)-1,n)-pow10(i-1)+1;
            if(ci<0) break;
            mi(B,ci);
            mul(A,B,A);
            ans=A[1][1]%mod;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    实验十四
    2
    解一元二次方程
    第一题
    输入四个人的年龄和姓名,排序后,按年龄,从小到大输出人员年龄及其姓名
    实验九
    实验8数组2 1.程序调试
    实验七4编写程序,输入一批学生的成绩,遇0或负数则输入结束,要求统计并输出优秀(大于85)、通过(60~84)和不及格(小于60)的学生人数。
    实验10 指针2
    作业4
  • 原文地址:https://www.cnblogs.com/harden/p/6637841.html
Copyright © 2011-2022 走看看