luoguP4999 烦人的数学作业
写在前面
这两天信息量有点大,需要好好消化一下,呼呼
\(f[i][j]\) 的转移式还是好理解的,但是对于其实际意义课上有点糊
求 \(ans_{1, x}\) 是感觉手动把数拆开看会好理解一点??
同级某巨佬wxf会用记忆化搜索做,我不会,太菜了
luoguP4999 烦人的数学作业
简述题意:
给定区间 \([ L , R ]\) ,求 \(L\) 到 \(R\) 区间内每个数字和 $ (1 \le L \le R \le 10^{18}) $ ,共 \(T\) 组数据 \((1 \le T \le 20)\)
Solution:
数位DP入门题?
设 \(f[i][j]\) ,第一维表示枚举到第 \(i\) 位, 第二维表示以 \(j\) 为最高位, \(f\) 数组用来存数字和
如 \(f[i][j]\) 中存的是 \([j000\cdots \ , \ j999\cdots]\) 这一区间的数字和,(其中每个数都有 \(i\) 位)
初始状态: \(f[1][i] = i \ (0 \le i \le 9)\)
考虑怎么转移,新枚举到的 \(f[i][j]\) 是在 \(f[i -1][k]\) 基础上加上新的一位,而因为新的一位后面可以跟 \(0 - 9\) 所有数,所以 \(k\) 的取值是 \(0 - 9\) , 因为这样的数的数量是 \(10^{i - 1}\) 个,所以转移方程就推出来啦:
\]
考虑最后怎么合并答案 \(ans_{l, r}\) ,
可以考虑先求出 \(ans_{1, l}\) 和 \(ans_{1, r + 1}\) 的答案,最后在进行合并(至于为什么是 \(l\) 和 \(r + 1\) 后面会进行解释
手模一个样例看看: \(ans_{1, 114514}\)
发现可以将它拆开:
& 114514 = \{ 0 - 99999 \} + \{ 100000 - 109999\} \\
& + \{ 110000 - 110999 ,111000 - 111999 , 112000 - 112999 , 113000 - 113999 \} \\
&+ \cdots \\
\end{aligned}
\]
用 \(f[i][j]\) 数组一个一个代换即可,前面多出的数可以用 \(sum\) 存一下在循环最后处理
在每一层后面处理一下前面多出的数(感觉说不清楚,感性理解一下/kk
可以发现循环到最后一位时并不会加上最后一个数,所以将所求区间整理一下就好啦
LL solve(LL x){
LL ans = 0, sum = 0;
LL s[22], len = 0;
for(;x; x /= 10) s[++len] = x % 10;
for(int i = len; i >= 1; --i){
for(int j = 0; j < s[i]; ++j){
ans = (ans + f[i][j]) % mod;
}
ans = (ans + sum * s[i] * quick_pow(10, i - 1) % mod) % mod;
sum = (sum + s[i]) % mod;
}
return ans;
}
(一开始感觉这样写比 \(Aliemo\)写的简单,后来发现并没有什么本质的区别)
code:
/*
Work by: Suzt_ilymics
Knowledge: 数位DP
Time: luogu最优解第五?
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int mod = 1e9+7;
LL read(){
LL s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + ch - '0', ch = getchar();
return s * w;
}
LL T, l, r, ans = 0;
LL f[22][22];
LL quick_pow(LL x, LL p){//快速幂
LL res = 1;
for( ; p; p >>= 1){
if(p & 1) res = res * x;
x = x * x;
}
return res;
}
void init(){//初始化
for(int i = 1; i <= 9; ++i) f[1][i] = i;
for(int i = 2; i <= 19; ++i){
for(int j = 0; j <= 9; ++j){
for(int k = 0; k <= 9; ++k){
f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
}
f[i][j] = (f[i][j] + j * quick_pow(10, i - 1)) % mod;
// cout<<f[i][j]<<" ";
}
// cout<<"\n";
}
}
LL solve(LL x){//求ans(1 - x)
LL ans = 0, sum = 0;
LL s[22], len = 0;
for(;x; x /= 10) s[++len] = x % 10;
for(int i = len; i >= 1; --i){
for(int j = 0; j < s[i]; ++j){
ans = (ans + f[i][j]) % mod;
}
ans = (ans + sum * s[i] * quick_pow(10, i - 1) % mod) % mod;
sum = (sum + s[i]) % mod;
}
return ans;
}
signed main()
{
init();
T = read();
while(T--){
l = read(), r = read();
printf("%lld\n", (solve(r + 1) - solve(l) + mod) % mod);
}
return 0;
}
/*
in:
2
1 1000000000000000000
1 1000000000000000000
out:
3970
3970
*/
luoguP4999 烦人的数学作业的更多相关文章
- P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...
- [洛谷P4999]烦人的数学作业
题目大意:定义$f(x)$表示$x$每一个数位(十进制)的数之和,求$\sum\limits_{i=l}^rf(i)$,多组询问. 题解:数位$DP$,可以求出每个数字的出现个数,再乘上每个数字的大小 ...
- 题解 P4999 【烦人的数学作业】
数位 dp. 设 \(dp_{q,i}\)(\(i\in\{0,1,2,3,4,5,6,7,8,9\}\))为 \(1\sim q\) 中 \(i\) 出现的次数,\(1\sim q\) 的数字和显然 ...
- 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘
2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...
- sdibt 1244 烦人的幻灯片
在这个OJ站还没号,暂时没提交,只是过了样例 真不愧是烦人的幻灯片,烦了我一小时 ---更新:OJ测试完毕,AC 烦人的幻灯片问题 Time Limit: 1 Sec Memory Limit: 6 ...
- bzoj2326: [HNOI2011]数学作业
矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...
- iOS 界面 之 EALayout 无需反复编译,可视化实时界面,告别Storyboard AutoLayout Xib等等烦人的工具
http://blog.csdn.net/fatherhui iOS开发,EALayout 无需反复编译,可视化实时界面,告别Storyboard AutoLayout Xib等等烦人的工具 EALa ...
随机推荐
- h5问题总结
一.下拉刷新上拉加载 主要依赖一款插件mescroll.js http://www.mescroll.com/ 简单好用.以前同事的用法是初始化执行执行上拉会调,页数从0开始,下拉重新加载当前地址走 ...
- JSP 的 4 种作用域?
page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...
- HTML表格样式
一.表格的表头 1 <html> 2 3 <body> 4 5 <h4>表头:</h4> 6 <table border="1" ...
- 翻译 | 30个 Python3 的最佳实践,技巧和窍门
1.使用 Python3 如果你关注 Python 的话,应该会知道 Python 2 已经于今年(2020 年)1 月 1 日正式弃用了.这份教程的很多例子都是只支持 Python 3 的,如果你还 ...
- 痞子衡嵌入式:MCUBootUtility v3.0发布,开始支持LPC, Kinetis啦
-- 痞子衡维护的NXP-MCUBootUtility工具距离上一个版本(v2.4.0)发布过去2个半月了,这一次痞子衡为大家带来了全新版本v3.0.0,从这个版本开始,NXP-MCUBootUtil ...
- dhcp分发地址以及静态路由设置
路由器R1配置: system-view [Huawei]sysname R1 [R1]user-interface console 0 [R1-ui-console0]idle-timeout 0 ...
- Kubernetes官方java客户端之八:fluent style
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Ts有限状态机
ts版本的有限状态机 最近做小游戏要做切换人物状态,花点时间写了一个有限状态机,使用语言为Ts,也可改成自己的语言 按照目前的逻辑,这个可以继续横向扩展,某些做流程管理 先上预览图 Fsm:状态机类 ...
- 深入理解static、volatile关键字
static 意思是静态的,全局的.被修饰的东西在一定范围内是共享的,被类的所有实例共享,这时候需要注意并发读写的问题. 只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们. ...
- C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻
这是道哥的第014篇原创 目录 一.前言 二.变量与指针的本质 1. 内存地址 2. 32位与64位系统 3. 变量 4. 指针变量 5. 操作指针变量 5.1 指针变量自身的值 5.2 获取指针变量 ...