洛谷传送门

题目:

Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩。他数数玩的具体规则是:

  1. 确定数数的进制$B$

  2. 确定一个数数的区间$[L, R]$

  3. 对于$[L, R] $间的每一个数,把该数视为一个字符串,列出该字符串的每一个(连续的)子串对应的$B$进制数的值。

  4. 对所有列出的数求和。现在Fish 数了一遍数,但是不确定自己的结果是否正确了。由于$[L, R] $较大,他没有多余精力去验证是否正确,你能写一个程序来帮他验证吗?

非常恶心的一道数位$DP$

首先是数位$DP$的常规套路,用$[1,R]$的答案减去$[1,L-1]$的答案

对于一个$B$进制数$S$,令$f_{S}$表示$S$所有后缀串所表示数的和,$l_{S}$表示数$S$的位数,现在在它末尾填上一个数$x$,则$F_{Sx}=F_{S}*B+x*(l_{S}+1)$

令$g_{S}$表示$S$所有子串所表示数的和,则$g_{Sx}=g_{S}*B+F_{Sx}$

我们要对$[1,S]$里的所有数进行统计,令$F_{i,0}$表示从高到低遍历到了第i位,未达到上限的所有数的$f_{x}$,$F_{i,1}$是达到上限的

可得$F_{i+1,0}=\sum_{x=1}^{B}(F_{i,0}*B+x*\sum (l_{S}+1))=B^{2}F_{i,0}+\frac{B(B-1)}{2}\sum (l_{S}+1)$

而$F_{i,1}$转移到$F_{i+1,0}$的也是类似的

显然我们还要维护一个数组$L_{i}$,表示前i位数中出现的数的$l_{x}$之和

因为要加上$\sum (l_{S}+1)$,还需要维护一个$Sum_{i}$,表示前i位数中出现的数的数量

这两个数组都很好维护

最后就是统计答案了,令$G_{i,0}$表示从高到低遍历到了第i位,未达到上限的所有数的$g_{x}$之和,$G_{i,1}$是达到上限的

因为每个$G_{i,0}$都有$B$次被转移,所以$G_{i+1,0}=B\cdot G_{i,0}+F_{i+1,0}$

而$G_{i,1}$转移到$G_{i+1,0}$的情况也是类似的

注意前导零的处理,我的方法是每遍历到新的一位,1~B每个数都还会作为一个新数的开头(除了第一位),把都加入状态里即可

 #include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 101000
#define N2 4201
#define M1 120
#define ll long long
#define dd double
#define uint unsigned int
#define idx(X) (X-'0')
using namespace std; const int mod=;
int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,B;
int f[N1][],g[N1][],s[N1][],l[N1][];
ll solve(int *a,int len)
{
memset(f,,sizeof(f));
memset(g,,sizeof(g));
memset(l,,sizeof(l));
memset(s,,sizeof(s));
ll ans=;
s[][]=a[]-,s[][]=;
l[][]=a[]-,l[][]=;
f[][]=1ll*a[]*(a[]-)/%mod;
f[][]=a[];
g[][]=f[][],g[][]=f[][];
for(int i=;i<len;i++)
{
s[i+][]=(1ll*s[i][]*B%mod + 1ll*s[i][]*a[i+]%mod + B-)%mod;
s[i+][]=s[i][];
l[i+][]=(1ll*(l[i][]+s[i][])*B%mod + 1ll*(l[i][]+s[i][])*a[i+]%mod + B-)%mod;
l[i+][]=(l[i][]+s[i][]);
f[i+][]=(1ll*f[i][]*B%mod*B%mod + 1ll*f[i][]*a[i+]%mod*B%mod + 1ll*(1ll*B*(B-)/%mod)*(l[i][]+s[i][]+)%mod + 1ll*(1ll*a[i+]*(a[i+]-)/%mod)*(l[i][]+s[i][])%mod)%mod;
f[i+][]=(1ll*f[i][]*B%mod + 1ll*a[i+]*(l[i][]+)%mod)%mod;
g[i+][]=(1ll*g[i][]*B%mod + 1ll*g[i][]*a[i+]%mod + f[i+][])%mod;
g[i+][]=(g[i][] + f[i+][])%mod;
}
return (g[len][]+g[len][])%mod;
}
int a[N1],b[N1],tmp[N1]; int main()
{
scanf("%d",&B);
scanf("%d",&n);
for(int i=n;i>=;i--)
tmp[i]=gint();
scanf("%d",&m);
for(int i=;i<=m;i++)
b[i]=gint();
tmp[]--;int k=;
while(tmp[k]<)
tmp[k]+=B,tmp[k+]--,k++;
if(tmp[n]==) n--;
for(int i=;i<=n;i++)
a[i]=tmp[n-i+];
ll ans1=solve(a,n);
ll ans2=solve(b,m);
printf("%lld\n",((ans2-ans1)%mod+mod)%mod);
return ;
}

BZOJ 3326 [SCOI2013]数数 (数位DP)的更多相关文章

  1. BZOJ_1662_[Usaco2006 Nov]Round Numbers 圆环数_数位DP

    BZOJ_1662_[Usaco2006 Nov]Round Numbers 圆环数_数位DP Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺 ...

  2. BZOJ_1026_[SCOI2009]windy数_数位DP

    BZOJ_1026_[SCOI2009]windy数_数位DP 题意:windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之 ...

  3. [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】

    题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...

  4. [bzoj 1026]windy数(数位DP)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 分析: 简单的数位DP啦 f[i][j]表示数字有i位,最高位的数值为j的windy数总 ...

  5. bzoj 1026 [SCOI2009]windy数(数位DP)

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4550  Solved: 2039[Submit][Sta ...

  6. BZOJ 3209 花神的数论题 数位DP+数论

    题目大意:令Sum(i)为i在二进制下1的个数 求∏(1<=i<=n)Sum(i) 一道非常easy的数位DP 首先我们打表打出组合数 然后利用数位DP统计出二进制下1的个数为x的数的数量 ...

  7. BZOJ 3209: 花神的数论题 [数位DP]

    3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...

  8. 【BZOJ】1662: [Usaco2006 Nov]Round Numbers 圆环数(数位dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1662 这道题折腾了我两天啊-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 果然 ...

  9. 【BZOJ】1026: [SCOI2009]windy数(数位dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 我果然很弱啊... 考虑数位dp.枚举每一位,然后限制下一位即可. 一定要注意啊!在dfs的时 ...

随机推荐

  1. java笔记线程的生命周期图解

  2. Objective-C NSString/NSMutableString

    创建于完成: 2018/02/05 总览: http://www.cnblogs.com/lancgg/p/8404975.html  字符串类  简介  字符码: Unicode  NSString ...

  3. HDU6012:Lotus and Horticulture(扫描线)(前缀和)

    传送门 题意 给出n种植物的适宜培育温度区间[l,r],低于下限获值c,高于上限获值b,其他获值a 分析 首先考虑应该尝试选择哪些点:区间的左右端点.与区间左右端点距离0.50.5的点,这样就一定可以 ...

  4. 暑期训练狂刷系列——Lightoj 1084 - Winter bfs

    题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1084 题目大意: 有n个点在一条以零为起点的坐标轴上,每个点最多可以移动k, ...

  5. _bzoj1798 [Ahoi2009]Seq 维护序列seq【线段树 lazy tag】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 注意,应保证当前节点维护的值是正确的,lazy tag只是一个下传标记,在下传时应即时 ...

  6. Zygote和System进程的启动过程、Android应用进程启动过程

    1.基本过程 init脚本的启动Zygote Zygote进程的启动 System进程的启动 Android应用进程启动过程 2.init脚本的启动 +------------+ +-------+ ...

  7. jmeter(七)函数

    JMeter函数是一些能够转化在测试树中取样器或者其他配置元件的域的特殊值.一个函数的调用就像这样:${_functionName(var1,var2,var3)},-functionName匹配函数 ...

  8. 阿里maven仓库地址

    在国内访问Maven仓库,连接速度太慢.下面是将中央仓库替换成阿里云的中央仓库的方法. 第一种,统一修改仓库地址 可以直接修改Mavenconf文件夹中的setting.xml文件,或者在.m2文件夹 ...

  9. 里氏替换原则中is和as分别的作用

    is 是用于检查对象是否指定类型兼容 if(empls[i] is SE){ ((SE)empls).SayHi(); } as 不用强转可以直接转换 if(empls[i] is SE){ SE s ...

  10. 内置函数isinstance和issubclass

    1. isinstance(obj,class) 判断对象obj是不是由class生成的对象. class Foo: pass obj=Foo() print(isinstance(obj,Foo)) ...