题目描述


题解

矩阵乘法

考虑把相同位数的数放到一起处理:

设有$k$位的数为$[l,r]$,那么枚举从大到小的第$i$个数(即枚举$r-i+1$),考虑其对$Concatenate(l..r)$的贡献:

$v_i=(r-i+1)10^{k(i-1)}$

所以要求的就是:

$\sum\limits_{i=1}^{r-l+1}(r-i+1)10^{k(i-1)}\mod m\ =\ \sum\limits_{i=0}^{r-l}(r-i)10^{ki}\mod m$

这个式子可以使用矩阵乘法解决。具体方法:

$\begin{bmatrix}(r-i)10^{ki}&10^{ki}&sum_{i-1}\end{bmatrix}*\begin{bmatrix}10^k&0&1\\-10^k&10^k&0\\0&0&1\end{bmatrix}=\begin{bmatrix}(r-i-1)10^{k(i+1)}&10^{k(i+1)}&sum_i\end{bmatrix}$

然后再乘上$10^{该位后面的位数}$即为它们对答案的贡献。把所有位数的数的贡献加起来即为答案。

注意需要unsigned long long。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
int m;
struct data
{
ull v[3][3];
data(ull x = 0) {memset(v , 0 , sizeof(v)) , v[0][0] = v[1][1] = v[2][2] = x;}
ull *operator[](int a) {return v[a];}
data operator*(data a)
{
data ans;
int i , j , k;
for(i = 0 ; i < 3 ; i ++ )
for(j = 0 ; j < 3 ; j ++ )
for(k = 0 ; k < 3 ; k ++ )
ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % m;
return ans;
}
}a;
data pow(data x , ull y)
{
data ans(1);
while(y)
{
if(y & 1) ans = ans * x;
x = x * x , y >>= 1;
}
return ans;
}
ull pow(ull x , ull y)
{
ull ans = 1;
while(y)
{
if(y & 1) ans = ans * x % m;
x = x * x % m , y >>= 1;
}
return ans;
}
int main()
{
ull i , j , n , now = 1 , ans = 0;
scanf("%llu%d" , &n , &m);
for(i = 1000000000000000000ull , j = 19 ; i ; i /= 10 , j -- )
{
if(n < i) continue;
a[0][0] = a[1][1] = i % m * 10 % m , a[1][0] = (m - a[0][0]) % m , a[0][2] = a[2][2] = 1 , a[0][1] = a[1][2] = a[2][0] = a[2][1] = 0;
a = pow(a , n - i + 1);
ans = (ans + (n % m * a[0][2] % m + a[1][2]) * now) % m , now = now * pow(10 , j * (n - i + 1)) % m , n = i - 1;
}
printf("%llu\n" , ans);
return 0;
}

【bzoj2326】[HNOI2011]数学作业 矩阵乘法的更多相关文章

  1. [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)

    Description Input Output Sample Input Sample Output HINT Source Solution 递推式长这样:$f[n]=f[n-1]*10^k+n$ ...

  2. BZOJ 2326: [HNOI2011]数学作业(矩阵乘法)

    传送门 解题思路 NOIp前看到的一道题,当时想了很久没想出来,NOIp后拿出来看竟然想出来了.注意到有递推\(f[i]=f[i-1]*poww[i]+i\),\(f[i]\)表示\(1-i\)连接起 ...

  3. BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘

    2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...

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

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

  5. bzoj2326: [HNOI2011]数学作业

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

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

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

  7. 【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]

    数学作业 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 输入文件只有一行为用空 ...

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

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

  9. bzoj2326:[HNOI2011]数学作业(分段矩阵乘法)

    题目大意:输入n(n<=10^18)和m,将1~n的整数连起来模m输出,比如n=13则输出12345678910111213模m的数. 设f[i]为1~i整数连起来模m的数,i的位数为k,则有f ...

随机推荐

  1. javascript--BOM的onload事件和onunload事件

    1.onload事件 onload,页面加载后执行,所谓页面加载完成,指页面上所有的元素创建完毕,引用的所有的外部资源(js.css.图片)等下载完毕. 所以onload执行的比较晚,因为如果页面上有 ...

  2. XPath知识点简单总结(思维导图)

    XPath是一种用于在XML文档中查找信息的语言,其对HTML也有很好的支持,所以在网络爬虫中可用于解析HTML文档.参考链接. 下图是XPath知识点的简单总结成思维导图:

  3. Linux 用户 和 组 快速了解

    1用户 (Linux中“只有超级管理员”才有权限操作 用户 和组) 1.1添加用户 useradd 命令 例如 :useradd hly //添加了一个新账户 hly 用户添加后 会存放在一个文件中, ...

  4. re模块(详解正则)

    re模块 imort re 1.\w \W print(re.findall('\w','ab 12\+- _*&')) #\w 匹配字母 数字 及下划线 执行结果:['a', 'b', '1 ...

  5. uva 540 - Team Queue(插队队列)

    首发:https://mp.csdn.net/mdeditor/80294426 例题5-6 团体队列(Team Queue,UVa540) 有t个团队的人正在排一个长队.每次新来一个人时,如果他有队 ...

  6. [HDU1512]Monkey King(左偏树)

    用并查集维护猴子们的关系,强壮值用左偏树维护就行了 Code #include <cstdio> #include <algorithm> #include <cstri ...

  7. Oracle错误记录

    1 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560 环境变量 右击计算机属性-->高级系统设置-->高级-->环境变量-->系统变量--> ...

  8. (转) Sqoop使用实例讲解

    原博客地址:http://blog.csdn.net/evankaka 摘要:本文主要讲了笔者在使用sqoop过程中的一些实例 一.概述与基本原理 Apache Sqoop(SQL-to-Hadoop ...

  9. java容器操作一

    List l = new ArrayList(); l.add(1); l.add("ne"); // 获取 System.out.println(l.get(0)); // 判断 ...

  10. luogu2387 [NOI2014]魔法森林

    这题和水管局长很像,枚举 \(a\) 的边然后维护关于 \(b\) 的最小生成树就可以了. 1A呐>_< #include <algorithm> #include <i ...