[luogu P3216] [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

很显然,我们可以得到一个递推式:fn=10^len(n)*fn-1+n。然后看到范围那么大,而式子很简单,所以我们就将原式转为矩阵。

显然,根据原式,可以构造出如下矩阵:

{{fn}               {{10^len(n),1,1}                        {{fn-1}

{n}       =         {0,1,1}                    *                 {n-1}

{1}}                 {0,0,1}                                      {1}}

但是,我们发现,10^len(n)并不是一个常数。

怎么办?分段来求。1~9一段,10~99一段,100~999一段……10^k~n一段。

这样,就可以避免这一项会变化的情况了。

看起来非常的easy,是不是?写起来就不会这么觉得了。

特别是边界和细节,非常难以处理。调了整整2个多小时。。

code:

 #include<bits/stdc++.h>
 #define LL unsigned long long
 using namespace std;
 LL n,m,po[],lim[];
 struct Mat {
     LL a[][]; Mat() {memset(a,,sizeof a);}
 }tran,ans;
 void pre() {
     tran.a[][]=,tran.a[][]=;
     tran.a[][]=,tran.a[][]=,tran.a[][]=;
     tran.a[][]=,tran.a[][]=,tran.a[][]=;
     po[]=,po[]=; ; i<=; i++) po[i]=po[i-]*;
     lim[]=; ; i<=; i++) lim[i]=lim[i-]*; lim[]=;
     ans.a[][]=,ans.a[][]=,ans.a[][]=;
 }
 Mat Mul(Mat u,Mat v) {
     Mat w; int i,j,k;
     ; i<; i++)
         ; j<; j++)
             ; k<; k++)
                 (w.a[i][j]+=u.a[i][k]*v.a[k][j])%=m;
     return w;
 }
 Mat Qpow(Mat b,LL p) {
     ) return b;
     Mat t=Qpow(b,p/); t=Mul(t,t);
     ==?t:Mul(t,b);
 }
 int main() {
     cin>>n>>m,pre();
     ; i<=; i++) ]<=n) {
         tran.a[][]=po[i+]%m;
         &&lim[i]-<=n) ans=Mul(Qpow(tran,lim[i]-lim[i-]),ans);
         ]+),ans);
     }else break;
     cout<<ans.a[][]<<'\n';
     ;
 }

[luogu P3216] [HNOI2011]数学作业的更多相关文章

  1. P3216 [HNOI2011]数学作业 (矩阵快速幂)

    P3216 [HNOI2011]数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NN 和 MM ,要求计算 Concatenate (1 .. N ...

  2. 洛谷P3216 [HNOI2011] 数学作业 [矩阵加速,数论]

    题目传送门 数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N和 M,要求计算 Concatenate (1 .. N)Mod M 的值,其中 C ...

  3. P3216 [HNOI2011]数学作业

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...

  4. 洛谷P3216 [HNOI2011]数学作业

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M,要求计算 Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...

  5. 洛谷 P3216 [HNOI2011]数学作业

    最近学了矩阵,kzj大佬推荐了我这一道题目. 乍一眼看上去,没看出是矩阵,就随便打了一个暴力,30分. 然后仔细分析了一波,发现蛮简单的. 结果全wa了,先看看下面的错误分析吧! 首先,设f[n]为最 ...

  6. [bzoj2326] [洛谷P3216] [HNOI2011] 数学作业

    想法 最初的想法就是记录当前 \(%m\) 值为cur,到下一个数时 \(cur=cur \times 10^x + i\) n这么大,那就矩阵乘法呗. 矩阵乘法使用的要点就是有一个转移矩阵会不停的用 ...

  7. bzoj2326: [HNOI2011]数学作业

    矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...

  8. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  9. [HNOI2011]数学作业 --- 矩阵优化

    [HNOI2011]数学作业 题目描述: 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算\(Concatenate(1..N)\; Mod\; ...

随机推荐

  1. URL简单梳理

    # DEBUG模式: 开启debug模式后,修改项目代码时按下ctrl+s可重启项目: 项目中出现bug时,浏览器与控制台会打印错误信息: 在生产环境中禁止开启DEBUG模式,有很大的安全隐患: 将D ...

  2. win10 安装Oracle 11g release 2

    参考资料: Oracle Database 11g Release 2 安装详解 - WIN 10 系统 准备工作: 安装 Oracle 11g 之前,要确保在此操作系统上未安装过 Oracle,或者 ...

  3. IDEA 的Class not found: "..."Empty test suite

    Junit测试的时候出现  IDEA 的Class not found: "..."Empty test suite问题. 尝试一下解决方法: 第一种方法: 1.modules&g ...

  4. python os.remove

    remove 只能删除文件,删除目录会报错 >>> import os >>> os.remove("/opt/xxx/server_log/test&q ...

  5. 测试char,varchar存储

    -- -- 表的结构 `user` -- DROP TABLE IF EXISTS `user`; CREATE TABLE IF NOT EXISTS `user` ( `id` int(11) N ...

  6. [osg][osgEarth][osgGA][原] EarthManipulator------基于oe的相机漫游器(浅析)

    知识基础:osg漫游器基础 class OSGEARTHUTIL_EXPORT EarthManipulator : public osgGA::CameraManipulator EarthMani ...

  7. PostgreSQL安装及使用教程二(zip解压方式)

    下载postgre包  下载地址:https://www.postgresql.org/download/ 选DOWNLOADS--Windows--zip archive--version10.6- ...

  8. P499 usebrass2

    有两种方式可以实现多态公有继承 1) 在派生类中重新定义基类的方法 2) 使用虚方法 如下是使用虚方法 brass.h #ifndef BRASS_H #define BRASS_H #include ...

  9. Java用FutureTask实现又返回值的线程

    要实现有返回值的多线程,具体代码如下: package thread; import java.util.concurrent.Callable; import java.util.concurren ...

  10. HTML如何实现滚动文字

    HTML如何实现滚动文字 一.总结 一句话总结:marquee标签,也可以用js和css来实现 marquee标签 也可jss和css <marquee><span style=&q ...