zjnu1749 PAROVI (数位dp)
Description
The distance between two integers is defined as the sum of the absolute result of subtracting their digits. For example, the distance between the numbers 4561 and 3278 is |4 – 3| + |5 - 2| + |6 - 7| + |1 - 8| = 12. If one of the numbers consists of fewer
digits than the other, we fill it with leading zeroes. Therefore, the distance between the numbers 32 and 5678 is |0 - 5| + |0 - 6| + |3 - 7| + |2 - 8| = 21.
You are given two integers A and B. Calculate the sum of distances between each pair of numbers belonging in the interval [A, B]!
Input
The first and only line of input contains integers A, B (1 ≤ A ≤ B ≤ 10^50000).
Output
The first and only line of output must contain the required number from the text. Given that the number could be extremely large, output answer modulo 1 000 000 007.
Sample Input
Sample Output
题意:定义两个数的距离是这两个数化成十进制后每一位上的数字差的绝对值,如果两个数长度不同,小的那个数用前导零补齐,现在给你两个数A,B,问[A,B]中所有取两个数情况的距离和 。
思路:观察可以发现,[A,B]区间内的距离和是每一位累加得到的,所以我们可以把每一位的sum统计出来。对于每一位,又可以发现,这一位的距离和等于num[0]*num[1]*(1-0)+num[0]*num[2]*(2-0)+...+num[8]*num[9]*(9-8),所以我们要算出每一位上0~9出现的次数。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 1100000000
#define pi acos(-1.0)
#define maxn 1005
#define MOD 1000000007
#define NN 50000
char s1[50050],s2[50050];
ll num[50050][10],num1[50050][10],num2[50050][10];
ll sumpre[50050],sumsuf[50050];
ll po[50050];
int len;
void init()
{
int i,j;
po[0]=1;
for(i=1;i<=NN;i++){
po[i]=(po[i-1]*10)%MOD;
}
}
void cal1(int len1)
{
int i,j;
sumpre[len1+1]=0;
for(i=len1;i>=1;i--){
sumpre[i]=(sumpre[i+1]*10+s1[i]-'0')%MOD;
}
sumsuf[0]=0;
for(i=1;i<=len1;i++){
sumsuf[i]=(sumsuf[i-1]+(s1[i]-'0')*po[i-1] )%MOD;
for(j=0;j<=9;j++){
if(j+'0'<s1[i]){
num1[i][j]=( (sumpre[i+1]+1)*po[i-1] )%MOD;
}
else if(j+'0'==s1[i]){
num1[i][j]=( sumpre[i+1]*po[i-1]%MOD+sumsuf[i-1]+1 )%MOD;
}
else if(j+'0'>s1[i]){
if(i==len1)num1[i][j]=0;
else num1[i][j]=( sumpre[i+1]*po[i-1] )%MOD;
}
}
}
for(i=len1+1;i<=len;i++){
num1[i][0]=sumsuf[len1]+1;
for(j=1;j<=9;j++)num1[i][j]=0;
}
}
void cal2(int len2)
{
int i,j;
sumpre[len2+1]=0;
for(i=len2;i>=1;i--){
sumpre[i]=(sumpre[i+1]*10+s2[i]-'0')%MOD;
}
sumsuf[0]=0;
for(i=1;i<=len2;i++){
sumsuf[i]=(sumsuf[i-1]+(s2[i]-'0')*po[i-1] )%MOD;
for(j=0;j<=9;j++){
if(j+'0'<s2[i]){ //这里如果当要算的值小于该位的值,那么num2[i][j]=(前面的数+1)*(10^(i-1) )
num2[i][j]=( (sumpre[i+1]+1)*po[i-1] )%MOD;
}
else if(j+'0'==s2[i]){ //这里如果当要算的值等于该位的值,那么num2[i][j]=前面的数*(10^(i-1) )+后面的数+1
num2[i][j]=( sumpre[i+1]*po[i-1]%MOD+sumsuf[i-1]+1 )%MOD;
}
else if(j+'0'>s2[i]){ //这里如果当要算的值大于该位的值,如果这位是最高位,那么num2[i][j]=0,否则num2[i][j]+=前面的数*(10^(i-1) )
if(i==len2)num2[i][j]=0;
else num2[i][j]=( sumpre[i+1]*po[i-1] )%MOD;
}
}
}
for(i=len2+1;i<=len;i++){
num2[i][0]=sumsuf[len2]+1;
for(j=1;j<=9;j++)num2[i][j]=0;
}
}
int main()
{
int n,m,i,j,len1,len2,k;
init();
while(scanf("%s%s",s1+1,s2+1)!=EOF)
{
len1=strlen(s1+1);
len2=strlen(s2+1);
reverse(s1+1,s1+1+len1); //因为算的是[A,B]间的数字个数,所以我们可以用[0,B]-[0,A-1]的,所以要先把A-1。
for(i=1;i<=len1;i++){
if(s1[i]>'0')break;
}
if(i==len1 && s1[i]=='1'){
len1--;
}
s1[i]=s1[i]-1;
for(j=1;j<i;j++){
s1[j]='9';
}
reverse(s2+1,s2+1+len2);
len=max(len1,len2);
cal1(len1);
cal2(len2);
ll sum=0;
for(i=1;i<=len;i++){
for(j=0;j<=9;j++){
num[i][j]=num2[i][j]-num1[i][j];
if(num[i][j]<0)num[i][j]+=MOD;
}
for(j=0;j<=9;j++){
for(k=j+1;k<=9;k++){
sum=(sum+num[i][k]*num[i][j]*(k-j)%MOD )%MOD;
}
}
}
printf("%lld\n",sum*2%MOD);
}
}
/*
1234 9999999
859571453
55 100
10810
*/
zjnu1749 PAROVI (数位dp)的更多相关文章
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- bzoj1026数位dp
基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...
- uva12063数位dp
辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...
- HDU2089 不要62[数位DP]
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 数位DP GYM 100827 E Hill Number
题目链接 题意:判断小于n的数字中,数位从高到低成上升再下降的趋势的数字的个数 分析:简单的数位DP,保存前一位的数字,注意临界点的处理,都是套路. #include <bits/stdc++. ...
- 数位dp总结
由简单到稍微难点. 从网上搜了10到数位dp的题目,有几道还是很难想到的,前几道基本都是模板题,供入门用. 点开即可看题解. hdu3555 Bomb hdu3652 B-number hdu2089 ...
- 数位DP入门
HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...
- 数位DP之奥义
恩是的没错数位DP的奥义就是一个简练的dfs模板 int dfs(int position, int condition, bool boundary) { ) return (condition ? ...
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
随机推荐
- LeetCode498 对角线遍历
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示. 示例: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], ...
- C中的dll 、lib和exe文件
参考:链接1 链接2 DLL 动态链接库(Dynamic Link Library,缩写为DLL),运行时加载是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.动态链接 ...
- Python基础语法2-数据类型
一,数字. 2. 字符串类型 3.列表 4.元组 5.集合 6.字典 7.数据类型转换: 8.序列操作
- CSS 奇思妙想边框动画
今天逛博客网站 -- shoptalkshow,看到这样一个界面,非常有意思: 觉得它的风格很独特,尤其是其中一些边框. 嘿嘿,所以来一篇边框特辑,看看运用 CSS,可以在边框上整些什么花样. bor ...
- 虚拟机Linux安装Oracle容器并实现局域网其他主机访问查询
该文涉及Docker下Oracle容器的安装,主机端口的设置实现局域网内终端均能连接上Oracle数据库,图解如下: 一.关于Docker安装oracle容器可以参考下面博文: https://blo ...
- 【MYSQL】MySQL5.6.37二进制安装
最近有个项目要用到mysql 于是在mysql的论坛中找到了一个5.6.37版本的 下面介绍怎么安装和使用mysql 下载地址: https://dev.mysql.com/downloads/mys ...
- 【ORACLE错误】SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled
执行set autotrace traceonly的时候,报错 SQL> set autotrace traceonly SP2-0618: Cannot find the Session Id ...
- 【Oracle】oracle pctfree和pctused详解
oracle pctfree和pctused详解 一.建立表时候,注意PCTFREE参数的作用 PCTFREE:为一个块保留的空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数 ...
- vxfs(Veritas File System)扩充目录大小
1.新增加一个磁盘并初始化 # vxdisk list # vxdisksetup -i 3pardata0_22 2.将新增加的磁盘合并到磁盘组中 # vxdg -g testdg01 adddis ...
- 人工智能"眼睛"——摄像头
摄像头机器视觉人工智能的"眼睛",其重要性在嵌入式领域不言而喻.但是如何理解和使用摄像头却是一个非常棘手的问题.本文主要针对调试摄像头过程中遇到的问题,对摄像头的基本原理及概述进行 ...