[BZOJ 2326] [HNOI2011] 数学作业 【矩阵乘法】
题目链接:BZOJ - 2326
题目分析
数据范围达到了 10^18 ,显然需要矩阵乘法了!
可以发现,向数字尾部添加一个数字 x 的过程就是 Num = Num * 10^k + x 。其中 k 是 x 的位数。
那么位数相同的数字用矩阵乘法处理就可以了。
[Num, x, 1] * [10^k, 0, 0] = [Num*10^k+x, x+1, 1]
[ 1, 0, 0]
[ 0, 1, 1]
枚举位数,做多次矩阵乘法。
其中两个整数相乘可能会爆 LL ,那么就用类似快速幂的慢速乘。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std; typedef long long LL; LL n, Mod; struct Matrix
{
int x, y;
LL A[5][5];
void Clear() {
memset(A, 0, sizeof(A));
}
void SetXY(int a, int b) {
x = a; y = b;
}
} M0, M_Ans, M_t; LL MulNum(LL a, LL b) {
LL f = a, ret = 0;
while (b) {
if (b & 1) {
ret += f;
if (ret > Mod) ret %= Mod;
}
b >>= 1;
f <<= 1;
if (f > Mod) f %= Mod;
}
return ret;
} Matrix Mul(Matrix Ma, Matrix Mb) {
Matrix ret;
ret.SetXY(Ma.x, Mb.y);
ret.Clear();
for (int i = 1; i <= ret.x; ++i) {
for (int j = 1; j <= ret.y; ++j) {
for (int k = 1; k <= Ma.y; ++k) {
ret.A[i][j] += MulNum(Ma.A[i][k], Mb.A[k][j]);
ret.A[i][j] %= Mod;
}
}
}
return ret;
} Matrix Pow(Matrix Ma, LL b) {
Matrix f, ret;
f = Ma;
ret.SetXY(Ma.x, Ma.y);
ret.Clear();
for (int i = 1; i <= ret.x; ++i) ret.A[i][i] = 1;
while (b) {
if (b & 1) ret = Mul(ret, f);
b >>= 1;
f = Mul(f, f);
}
return ret;
} int main()
{
scanf("%lld%lld", &n, &Mod);
LL Temp, Ans;
M0.SetXY(1, 3);
M0.Clear();
M0.A[1][1] = 0; M0.A[1][2] = 1; M0.A[1][3] = 1;
M_t.SetXY(3, 3);
Temp = 1;
for (int i = 1; i <= 18; ++i) {
Temp *= 10ll;
if (Temp > n) break;
M_t.Clear();
M_t.A[1][1] = Temp;
M_t.A[2][1] = M_t.A[2][2] = M_t.A[3][2] = M_t.A[3][3] = 1;
M_t = Pow(M_t, Temp - Temp / 10);
M0 = Mul(M0, M_t);
}
M_t.Clear();
M_t.A[1][1] = Temp;
M_t.A[2][1] = M_t.A[2][2] = M_t.A[3][2] = M_t.A[3][3] = 1;
M_t = Pow(M_t, n - Temp / 10 + 1);
M0 = Mul(M0, M_t);
Ans = M0.A[1][1];
printf("%lld\n", Ans);
return 0;
}
[BZOJ 2326] [HNOI2011] 数学作业 【矩阵乘法】的更多相关文章
- BZOJ 2326: [HNOI2011]数学作业(矩阵乘法)
传送门 解题思路 NOIp前看到的一道题,当时想了很久没想出来,NOIp后拿出来看竟然想出来了.注意到有递推\(f[i]=f[i-1]*poww[i]+i\),\(f[i]\)表示\(1-i\)连接起 ...
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...
- bzoj 2326: [HNOI2011]数学作业【dp+矩阵快速幂】
矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式, ...
- bzoj 2326: [HNOI2011]数学作业
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #defin ...
- [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)
Description Input Output Sample Input Sample Output HINT Source Solution 递推式长这样:$f[n]=f[n-1]*10^k+n$ ...
- 【bzoj2326】[HNOI2011]数学作业 矩阵乘法
题目描述 题解 矩阵乘法 考虑把相同位数的数放到一起处理: 设有$k$位的数为$[l,r]$,那么枚举从大到小的第$i$个数(即枚举$r-i+1$),考虑其对$Concatenate(l..r)$的贡 ...
- BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘
2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...
- [HNOI2011]数学作业 --- 矩阵优化
[HNOI2011]数学作业 题目描述: 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算\(Concatenate(1..N)\; Mod\; ...
- 【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]
数学作业 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 输入文件只有一行为用空 ...
随机推荐
- UIApplication对象及其代理UIApplicationDelegate[转]
在开发过程中我们需要一些全局对象来将程序的各个部分连接起来,这些全局对象中最重要的就是UIApplication对象.但在实际编程中我们并不直接和UIApplication对象打交道,而是和其代理打交 ...
- android十六进制颜色代码转换为int类型数值
android开发中将十六进制颜色代码转换为int类型数值方法:Color.parseColor("#00CCFF")返回int数值;
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航 系列目录 本节主要知识点是easyui ...
- my.cnf已经存在,影响安装--mysql
Found existing config file ./my.cnf on the system. Because this file might be in use, it was not rep ...
- 在Eclipse中显示空格(space)和制表符(tab)
显示空格(space)和制表符(tab)设置: Window->Preferences->General->Editors->Text Editors->Show whi ...
- javascript 高级程序设计(三)-数据类型
ECMAScript 中所有类型的值都有与这两个Boolean值等价的值 数据类型 转换为true的值 转换为false的值 Boolean true false( String ...
- U3D 脚本添加和获得对象
有时候,一开始可能没有对象,而是由于某种触发,产生的一个对象,这里讲解下,如何通过脚本来创建一个对象: 这是通过脚本创建一个立方体: using UnityEngine; using System.C ...
- java.util.Random深入理解
java.util.Random next方法的原理 比较好的参考文档: http://isky001.iteye.com/blog/1339979 package random.utilrandom ...
- 一次利用MSSQL的SA账户提权获取服务器权限
遇到小人,把服务器整走了 自己手里只有sql server的sa账号密码 模糊记起之前用这个账户提权读取文件的事 百度之,发现相关信息一堆堆 各种工具也用了不少 发现不是语法错误就是权限不够 无奈之下 ...
- 将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据
领导让在存储过程中批量添加数据,找出效率最高的,我看到后台代码后,发现可以将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据,知道还有其 ...