洛谷传送门

题目:

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. ubuntu /etc/profile和/etc/environment的比较 (转载)

    转自:http://blog.csdn.net/teamlet/article/details/8257853 先将export LANG=zh_CN加入/etc/profile ,退出系统重新登录, ...

  2. 51nod 1239 欧拉函数之和【欧拉函数+杜教筛】

    和bzoj 3944比较像,但是时间卡的更死 设\( f(n)=\sum_{d|n}\phi(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1}^{n}\phi(i) ...

  3. Java实现Excel数据批量导入数据库

    Java实现Excel数据批量导入数据库 概述: 这个小工具类是工作中的一个小插曲哦,因为提数的时候需要跨数据库导数... 有的是需要从oracle导入mysql ,有的是从mysql导入oracle ...

  4. QB学堂济南游记

    七天很快就过去了,今天的测试意味着集训也将结束.回首七天来,与许多dalao同处一室,见识到了各种厉害的老师.厉害的算法.厉害的数据结构. 前两天jzh与yl老师讲课的时候还是全程在线,然而讲到数据结 ...

  5. 《Windows核心编程系列》十二谈谈Windows内存体系结构

    Windows内存体系结构 理解Windows内存体系结构是每一个励志成为优秀的Windows程序员所必须的. 进程虚拟地址空间 每个进程都有自己的虚拟地址空间.对于32位操作系统来说,它的地址空间是 ...

  6. Qt事件系统之五:事件过滤器和事件的发送

    Qt提供了事件过滤器来实现在一个部件中监控其他多个部件的事件.事件过滤器与其他部件不同,它不是一个类,只是由两个函数组成的一种操作,用来完成一个部件对其他部件的事件的监视.这两个函数分别是 insta ...

  7. [ZPG TEST 116] 最小边权和【生成树相关】

    先将输入的边从小到大排序,对于一条边,它一定连接着两个联通块u与v,那么这条变对于答案的贡献是siz[u] * siz[v] * (边权 + 1) - 1,别问为什么这太显然了,一想就懂... #in ...

  8. h5学习-h5嵌入android中

    嵌入Android中的h5界面: 将此页面复制到android项目中的assets目录下边: <!DOCTYPE html> <html lang="en"> ...

  9. (四)SpringIoc之Bean装配

    在pom.xml的依赖 <dependencies> <!--测试包--> <dependency> <groupId>junit</groupI ...

  10. css3 transform + deviceorientation实现图片旋转效果

    1. 陀螺仪deviceorientation的使用,参考<关于陀螺仪deviceorientation>https://segmentfault.com/a/11900000071838 ...