洛谷传送门

题目:

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. Winpcap笔记4之不用回调函数捕获数据包

    函数1: pcap_next_ex(pcap_t*                       p, struct pcap_pkthdr**   pkt_header, const u_char*  ...

  2. UVa 1363 Joseph's Problem (数论)

    题意:给定 n,k,求 while(i <=n) k % i的和. 析:很明显是一个数论题,写几个样例你会发现规律,假设 p = k / i.那么k  mod i = k - p*i,如果 k ...

  3. ReplacementShader 测试

    简介 参考网页 SetReplacementShader(Shader shader, string replacementTag); 参数中的replacementTag,是Shader中Tags中 ...

  4. 洛谷P4114 Qtree1(树链剖分+线段树)

    传送门 LCT秒天秒地用什么树剖 这题可以算是树剖的比较裸的题目了 把每一条边的权值下放到他两边的点中深度较深的那个 然后直接用树剖+线段树带进去乱搞就可以了 //minamoto #include& ...

  5. 2017 ACM-ICPC Asia East Final T1

    好弱啊只会T1,在Chemist&&wxh两位dalao的指导下搞懂. 题解如下.[手写版本 滑稽 code #include<bits/stdc++.h> using n ...

  6. git基本操作(入门)

    下面以一个最简单的开发过程,呈现git最基本的操作命令 1.下载代码(以code命名仓库为例) git clone xxxxx/code.git cd code 2.查看所有分支 git branch ...

  7. cmdb客户端服务器信息采集一

    #cmdb脚本程序一 #!/usr/bin/python # coding:utf-8 """ 采集机器自身信息 1 主机名 2 内存 3 ip与mac地址 4 cpu信 ...

  8. JAVA启动参数三:非Stable参数

    前面我们提到用-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了:但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX: ...

  9. 2017 JUST Programming Contest 3.0 D. Dice Game

    D. Dice Game time limit per test 1.0 s memory limit per test 256 MB input standard input output stan ...

  10. HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2 历史演变和设计思路(详)*

    HTTP 协议是互联网的基础协议,也是网页开发的必备知识,最新版本 HTTP/2 更是让它成为技术热点. 本文介绍 HTTP 协议的历史演变和设计思路. 一.HTTP/0.9 HTTP 是基于 TCP ...