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,如果直接记录下数字, ...
随机推荐
- Spring Boot超详细用户管理项目(零)——开发前准备
开始前的软件准备:(编写中:未完成) 使用软件介绍: Java版本:Java SE 11(LTS) 开发工具:IDEA(2020.3版本) Linux系统: 数据库: Java 版本:Java SE ...
- 安装sendmail
yum install -y sendmail yum install -y sendmail-cf 启动 service sendmail start 发送邮件 cat nihao.txt |mai ...
- 【MySQL】centos6中/etc/init.d/下没有mysqld启动文件,怎么办
如果/etc/init.d/下面没有mysqld的话,service mysqld start也是不好使的,同样,chkconfig mysqld on也是不能用 解决办法: 将mysql的mysql ...
- 【Linux】saltstack的使用详解 超详细
一.salt常用命令 salt 该命令执行salt的执行模块,通常在master端运行,也是我们最常用到的命令 salt [options] '<target>' <function ...
- 浅谈JavaScript代码性能优化
可以通过https://jsbench.me/测试网站完成性能测试. 一.慎用全局变量 1.全局变量定义在全局执行上下文,是所有作用域链的顶端,在局部作用域中没找到的变量都会到全局变量中去查找,所以说 ...
- 1.2V转5V稳压芯片,低功耗电路
PW5100具有将低输入电压0.7V-5V之间的范围,升压型,升压到5V的稳定电压输出. 可以使其镍氢电池1.2V稳定输出5V的1.2V转5V芯片. PW5100具有极低的输入静态功耗,1.2V时,应 ...
- 浅谈JavaScript代码性能优化2
一.减少判断层级 从下图代码中可以明显看出,同样的效果判断层级的减少可以优化性能 二.减少作用域链查找层级 简单解释下,下图中第一个运行foo函数,bar函数内打印name,bar作用域内没有name ...
- 解决maven中某些依赖无法下载,手动安装Maven依赖
<!--先下载jar包,然后在仓库中手动安装,下面是遇到的两个例子--> <!--第一个--> mvn install:install-file -Dfile=D:\kaptc ...
- Linux日志文件(常见)及其功能
日志文件是重要的系统信息文件,其中记录了许多重要的系统事件,包括用户的登录信息.系统的启动信息.系统的安全信息.邮件相关信息.各种服务相关信息等.这些信息有些非常敏感,所以在 Linux 中这些日志文 ...
- https://www.cnblogs.com/AloneSword/p/3209653.html
proc/sys/net/ipv4/下各项的意义 - 孤剑 - 博客园 https://www.cnblogs.com/AloneSword/p/3209653.html