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,如果直接记录下数字, ...
随机推荐
- readhat6.5下安装weblogic10.3.6
转载自:http://www.mianhuage.com/752.html 1.安装前准备 1.1.准备安装包generic.jar1.2.创建weblogic用户及用户组创建组命令:groupadd ...
- 【Java并发集合】ConcurrentHashMap源码解析基于JDK1.8
concurrentHashMap(基于jdk1.8) 类注释 所有的操作都是线程安全的,我们在使用时无需进行加锁. 多个线程同时进行put.remove等操作时并不会阻塞,可以同时进行,而HashT ...
- 【Spring】Spring的数据库开发 - 2、Spring JdbcTemplate的常用方法(execute、update、query)
Spring JdbcTemplate的常用方法 文章目录 Spring JdbcTemplate的常用方法 execute() update() query() 简单记录-Java EE企业级应用开 ...
- Python利用最优化算法求解投资内部收益率IRR【一】
一. 内部收益率和净现值 内部收益率(Internal Rate of Return, IRR)其实要和净现值(Net Present Value, NPV)结合起来讲.净现值指的是某个投资项目给公司 ...
- top有用的开关控制命令
[原创]本文为原创博文,转发请注明出处:https://www.cnblogs.com/dingbj/p/top_command.html 今天偶然用到top命令,在动态刷新的界面上输入h顺便看了下帮 ...
- oralce move和shrink释放高水位
转自:https://blog.51cto.com/fengfeng688/1955137 move和shrink的共同点: 收缩段,消除部分行迁移,消除空间碎片,使数据更紧密 shrink用法: 语 ...
- STM32驱动LCD原理
TFTLCD即薄膜晶体管液晶显示器.它与无源TN-LCD.STN-LCD的简单矩阵不同,它在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性 ...
- TCP服务器程序
Linux下编写TCP服务器调用的函数顺序为:socket -> bind -> listen -> accept -> recv/send socket 参见:http:// ...
- python多线程和GIL全局解释器锁
1.线程 线程被称为轻量级进程,是最小执行单元,系统调度的单位.线程切换需要的资源一般,效率一般. 2.多线程 在单个程序中同时运行多个线程完成不同的工作,称为多线程 3.并 ...
- SpringMVC听课笔记(一:SpringMVC概述)
地址 :https://www.bilibili.com/video/av14907450 版本:4.x 概述: 概要: 一:SpringMVC概述 二:SpringMVC的 HelloWorld 三 ...