这题是显然的数位$dp$,然而我居然写了一个下午!!!

我们不难想到差分,令$solve(x,y)$表示从第一个数字在区间$[0,x]$,第二个数字在区间$[0,y]$的答案。

不难发现题目中给了你一对$A$,$B$,答案显然为$solve(B,B)-2solve(A-1,B)+solve(A-1,A-1)$。

考虑如何求解$solve(x,y)$函数,令$n=max(len(x),len(y))$,其中$len(p)$表示数字$p$在十进制下的长度(以下的位均代表十进制位)。

令$f[i]$表示数字$x$在模意义下前$i$位的值,令$F[i]$表示数字$x$在模意义下后$n-i+1$位的值。

同理,我们处理出$g[i]$和$G[i]$。

令$mi[i]$表示模意义下$10^i$的值,$Mi[i]$表示模意义下$10^(n-i+1)$的值。

令$ans[i][j][k]$表示第一个数字的第$i$位为$j$,第二个数字的第$i$位为$k$时的答案。

设第一个数字第$i$位为$j$的数字个数为$mul1$,第二个数字第$i$位为$k$的个数为$mul2$。

下面考虑如何求$mul1$,设$x[i]$为数字$x$的第i位,$num[i]$为数字$x$前$i$位构成的数,$Num[i]$为数字$x$后$i$位构成的数。

当$x[i]<j$时,$mul1=(f[i-1]+1)\times Mi[i+1]$,这里可以理解为前$i$位填一个数不大于$num[i-1]$的数,或者全填$0$,后$n-i$个数随便填的方案数。

当$x[i]==j$时,$mul1=f[i-1]\times Mi[i+1]+F[i+1]+1$ ,这里可以理解为前$i$位填一个小于$num[i-1]$的数,后$n-i$个数随便填的方案数,加上前$i$个数和$x$的前i个数相同,后n-i个数填写不大于F[i+1]的方案数。

当x[i]>j时,$mul1=f[i-1]\times Mi[i+1]$,这里可以理解为前$i$位填一个小于$num[i-1]$的数,后$n-i$位随便填的方案数。

求$mul2$同理

那么显然,$ans[i][j][k]=mul1\times mul2$。$solve(x,y)=\sum_{i=1}^{n}\sum_{j=0}^{9}\sum_{k=0}^{9}ans[i][j][k]$。

最终的答案为$solve(B,B)-2solve(A-1,B)+solve(A-1,A-1)$。考虑到$A$跟$B$的位数可能很大,这个减法需要用高精度。

完结撒花,注意细节。

 #include<bits/stdc++.h>
#define MOD 1000000007
#define M 100005
#define LL long long
using namespace std;
char c[M]={};
struct bign{
LL a[M+],len; bign(){memset(a,,sizeof(a));}
void rd(){
scanf("%s",c); len=strlen(c);
for(LL i=;i<len;i++) a[M-i]=c[len-i-]-'';
}
void jian(){
for(LL i=M,g=;i&&g;i--){
LL s=a[i]-g;
if(s>=) a[i]=s,g=;
else a[i]=s+,g=;
}
for(LL i=;i<=M;i++)
if(a[i]!=){
len=M-i+;
return;
}
}
}A,B,L,R;
LL f[M]={},g[M]={},F[M]={},G[M]={},mi[M]={},Mi[M]={},a[M]={},b[M]={},n; LL solve(){
n=max(A.len,B.len); LL res=;
mi[]=; for(LL i=;i<=n;i++) mi[i]=mi[i-]*%MOD;
F[n+]=G[n+]=;
for(LL i=;i<=n;i++) a[i]=A.a[M-n+i],b[i]=B.a[M-n+i];
for(LL i=;i<=n;i++) f[i]=(f[i-]*+a[i])%MOD,g[i]=(g[i-]*+b[i])%MOD;
for(LL i=n;i;i--) F[i]=(F[i+]+a[i]*mi[n-i])%MOD,G[i]=(G[i+]+b[i]*mi[n-i])%MOD;
Mi[n+]=; for(LL i=n;i;i--) Mi[i]=Mi[i+]*%MOD; for(LL i=;i<=n;i++){
for(LL num1=;num1<;num1++)
for(LL num2=;num2<;num2++){
LL cha=abs(num1-num2),mul1=,mul2=;
if(num1<a[i]) mul1=(f[i-]+)*mi[n-i]%MOD;
if(num1==a[i]) mul1=(f[i-]*Mi[i+]%MOD+F[i+]+)%MOD;
if(num1>a[i]) mul1=f[i-]*Mi[i+]%MOD; if(num2<b[i]) mul2=(g[i-]+)*mi[n-i]%MOD;
if(num2==b[i]) mul2=(g[i-]*Mi[i+]%MOD+G[i+]+)%MOD;
if(num2>b[i]) mul2=g[i-]*Mi[i+]%MOD; res=(res+mul1*mul2%MOD*cha)%MOD;
}
}
return res;
} int main(){
L.rd(); R.rd();
LL ans=;
A=R; B=R;
ans=solve();
A=L; A.jian();
ans=(ans-*solve()+*MOD)%MOD;
B=L; B.jian();
ans=(ans+solve())%MOD;
cout<<ans<<endl;
}

【xsy1611】 数位dp 数位dp的更多相关文章

  1. [DP]数位DP总结

     数位DP总结 By Wine93 2013.7 1.学习链接 [数位DP] Step by Step   http://blog.csdn.net/dslovemz/article/details/ ...

  2. CodeForces 54C-First Digit Law(数位,概率dp)

    题意: 给你n个区间,在每个区间里各取一个数(随机取),求这n个数中超过K%的数是首位为1数的概率 分析: dp[i][j]取前i个数,有j个是首位为1的数的概率 易知,dp[i][j]=dp[i-1 ...

  3. 数位dp模板 [dp][数位dp]

    现在才想到要学数位dp,我是不是很弱 答案是肯定的 以一道自己瞎掰的题为模板 //题: //输入数字n //从0枚举到n,计算这n+1个数中含有两位数a的数的个数 //如12930含有两位数93 #i ...

  4. Codeforces Round #235 (Div. 2) D. Roman and Numbers 状压dp+数位dp

    题目链接: http://codeforces.com/problemset/problem/401/D D. Roman and Numbers time limit per test4 secon ...

  5. Codeforces 946 课程表背包DP 数位DFS构造

    A B 给你A,B 两个数      1.a=0 OR b=0 break      2.a>=2b a=a-2b        3.b>=2a b=b-2a 如果只是单纯模拟肯定会超时 ...

  6. DP套DP HDOJ 4899 Hero meet devil(国王的子民的DNA)

    题目链接 题意: 给n长度的S串,对于0<=i<=|S|,有多少个长度为m的T串,使得LCS(S,T) = i. 思路: 理解的不是很透彻,先占个坑. #include <bits/ ...

  7. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  8. 377. Combination Sum IV——DP本质:针对结果的迭代,dp[ans] <= dp[ans-i] & dp[i] 找三者关系 思考问题的维度+1,除了数据集迭代还有考虑结果

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  9. HDU4960Another OCD Patient(间隙dp,后座DP)

    Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Ot ...

  10. [CF697D]Puzzles 树形dp/期望dp

    Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...

随机推荐

  1. 上海第八中学 shader

    http://shiba.hpe.cn/jiaoyanzu/wuli/soft/xna.aspx?classId=4

  2. Silverlight或WPF动态绑定图片路径问题,不用Converter完美解决

    关于Silverlight或WPF动态绑定图片路径问题,不用Converter完美解决, 可想,一个固定的字符串MS都能找到,按常理动态绑定也应该没问题的,只需在前面标记它是一个Path类型的值它就能 ...

  3. Linux服务器部署系列之七—OpenLDAP篇

    LDAP(轻量级目录访问服务),通过配置这个服务,我们也可以在linux下面使用目录的形式管理用户,就像windows下面的AD一样,方便我们管理.下面我们就一起来配置openldap服务.本文运行环 ...

  4. b4和tncl_extract_UNCL_new

    # -*- coding:utf-8 -*- import re ''' 适应新版本 注意: 1)17A文件改完后缀后,需要转为UTF-8无BOM格式,才能正确处理. 2)fr = open(file ...

  5. cxf-rs 和 swagger 的点

    1. 从web.xml 说起 <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class ...

  6. 4) Maven 安装

    # ----------------------------------------------------------------------------# Maven2 Start Up Batc ...

  7. Android ContentProvider和Uri详解

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据, 也就是说你可以通过ContentProvider把应用中的数据共享 ...

  8. nodejs 获取文件的编码方式

    使用nodejs获取文件夹内文件的编码方式:使用jschardet模块. 下面的代码还有问题,没有添加结束的语句,没有判断应该在哪执行res.send(). res.send()不能放在forEach ...

  9. git 在非空文件夹clone新项目

    在非空目录下 git clone 项目时会提示错误信息: fatal: destination path '.' already exists and is not an empty director ...

  10. JS的__proto__与prototype

    一.prototype和__proto__的概念 prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象.它是显示修改对象的原型的属性. __p ...