BZOJ 3326 [SCOI2013]数数 (数位DP)
题目:
Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩。他数数玩的具体规则是:
确定数数的进制$B$
确定一个数数的区间$[L, R]$
对于$[L, R] $间的每一个数,把该数视为一个字符串,列出该字符串的每一个(连续的)子串对应的$B$进制数的值。
对所有列出的数求和。现在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)的更多相关文章
- BZOJ_1662_[Usaco2006 Nov]Round Numbers 圆环数_数位DP
BZOJ_1662_[Usaco2006 Nov]Round Numbers 圆环数_数位DP Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺 ...
- BZOJ_1026_[SCOI2009]windy数_数位DP
BZOJ_1026_[SCOI2009]windy数_数位DP 题意:windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之 ...
- [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】
题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...
- [bzoj 1026]windy数(数位DP)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 分析: 简单的数位DP啦 f[i][j]表示数字有i位,最高位的数值为j的windy数总 ...
- bzoj 1026 [SCOI2009]windy数(数位DP)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4550 Solved: 2039[Submit][Sta ...
- BZOJ 3209 花神的数论题 数位DP+数论
题目大意:令Sum(i)为i在二进制下1的个数 求∏(1<=i<=n)Sum(i) 一道非常easy的数位DP 首先我们打表打出组合数 然后利用数位DP统计出二进制下1的个数为x的数的数量 ...
- BZOJ 3209: 花神的数论题 [数位DP]
3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...
- 【BZOJ】1662: [Usaco2006 Nov]Round Numbers 圆环数(数位dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1662 这道题折腾了我两天啊-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 果然 ...
- 【BZOJ】1026: [SCOI2009]windy数(数位dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1026 我果然很弱啊... 考虑数位dp.枚举每一位,然后限制下一位即可. 一定要注意啊!在dfs的时 ...
随机推荐
- Tomcat相关的LNMT和LAMT
Tomcat相关的LNMT和LAMT LNMT:Linux Nginx MySQL Tomcat Client (http) --> nginx (reverse proxy)(http) -- ...
- bzoj 1927 [Sdoi2010]星际竞速【最小费用最大流】
果然还是不会建图- 设\( i \)到\( j \)有通路,代价为\( w[i][j] \),瞬移到i代价为\( a[i] \),瞬移到i代价为\( a[j] \),逗号前是流量. 因为每个点只能经过 ...
- [SDOI2013]保护出题人
题目 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企图攻击铭铭的家.而你作为SDOI2013的参赛者 ...
- poj 1061 青蛙约会(扩展欧几里德)
题目链接: http://poj.org/problem?id=1061 题目大意: 中文题目,题意一目了然,就是数据范围大的出奇. 解题思路: 假设两只青蛙都跳了T次,可以列出来不定方程:p*l + ...
- 准确计算CoreText高度的方法:
- (int)getAttributedStringHeightWithString:(NSAttributedString *) string WidthValue:(int) width { ; ...
- 前台js获得json数据
$.ajax({ type:"post", url:"testAction.action", data:{ classId:classId }, success ...
- ABP教程(三)- 开始一个简单的任务管理系统 – 后端编码
上一篇 我们介绍了什么是ABP,这一篇我们通过原作者的”简单任务系统”例子,演示如何运用ABP开发项目 创建实体 一般来说任务是需要分配给人来做的,所以我们创建两个实体模型类:Task和Persion ...
- AJPFX实列判断一个字符串是不是对称字符串
import java.util.Scanner; /** * 判断一个字符串是否是对称字符串 */ public class StringDemo { public static vo ...
- fatal: Authentication failed for 问题解决
执行以下code git config --system --unset credential.helper 参考地址: https://www.jianshu.com/p/8a7f257e07b8
- iOS游戏开发之UIDynamic
iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ...