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,如果直接记录下数字, ...
随机推荐
- C中的dll 、lib和exe文件
参考:链接1 链接2 DLL 动态链接库(Dynamic Link Library,缩写为DLL),运行时加载是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.动态链接 ...
- 执行py文件需要可执行权限吗?
案例解析 这个问题描述起来有点违反直觉,要执行一个文件难道不应该需要可执行权限吗?让我们先来看一个例子: # module1.py def test(): print ('hello world!') ...
- dd命令的详细介绍
1.命令简介 dd 的主要选项: 指定数字的地方若以下列字符结尾乘以相应的数字: b=512, c=1, k=1024, w=2, xm=number m if=file #输入文件名,缺省为标准输 ...
- ctfhub技能树—sql注入—Cookie注入
手注 打开靶机 查看页面信息 查找cookie 测试是否为cookie注入 抓包 尝试注入 成功查询到数据库名 查询表名 查询字段名 查询字段信息 成功拿到flag sqlmap 查询数据库名 pyt ...
- SpringCloud Alibaba Nacos注册中心源码浅析
一.前置了解 1.1 简介 Nacos是一款阿里巴巴推出的一款微服务发现.配置管理框架.我们本次对将对它的服务注册发现功能进行简单源码分析. 1.2 流程 Nacos的分析分为两部分,一部分是我们的客 ...
- uniapp根据登录用户的角色动态的改变tabBar的数量和内容
此文章借鉴于https://blog.csdn.net/fuyuumiai/article/details/109746357,在此基础上修改小部分内容,适用于我这种uniapp小白 介绍: 现在我们 ...
- Memcached与Redis对比及其优劣分析
国外讨论 本文主要总结缓存Redis和Memcached的区别,总结之前先参考外国知乎上的一篇问答:<Is memcached a dinosaur in comparison to Redis ...
- 浅析Linux启动流程
Linux系统启动流程 Linux 系统的启动,从计算机开机通电自检开始,一直到登陆系统,需要经历多个过程.了解 Linux 的启动过程,有助于了解 Linux 系统的结构,也对系统的排错有很大的帮助 ...
- 整合阿里云OSS
整合阿里云OSS 一.对象存储OSS 为了解决海量数据存储与弹性扩容,采用云存储的解决方案- 阿里云OSS. 1.开通"对象存储OSS"服务 (1)申请阿里云账号 (2)实名认证 ...
- JAVAV EMAIL
package a; import java.util.Date;import java.util.Properties;import javax.mail.Authenticator;import ...