题解-[SDOI2014]数数

[SDOI2014]数数这题的前置知识是AC自动机和dp,前置题目是 [JSOI2007]文本生成器,前置题目我写的题解 题解-[JSOI2007]文本生成器。我的讲解假设你做过上面那道题。这题比上面那题多个条件,我因此多调了 333 个小时。多的条件:答案要不大于整数 nnn。所以AC自动机部分同上,改变dp部分。解:dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示...
摘要由CSDN通过智能技术生成

[SDOI2014]数数

这题的前置知识是AC自动机和dp,前置题目是 [JSOI2007]文本生成器,前置题目我写的题解 题解-[JSOI2007]文本生成器。我的讲解假设你做过上面那道题。

这题比上面那题多个条件,我因此多调了 3 3 3 个小时。多的条件:答案要不大于整数 n n n。所以AC自动机部分同上,改变dp部分。

解: d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 表示文本串(幸运数)长度为 i i i,结尾是AC自动机上的节点 j j j k k k 表示这个文本串下一个字符是否受 n n n 某个数位大小的限制(如果受限制, k = 1 k=1 k=1;否则, k = 0 k=0 k=0)。 m k [ i ] mk[i] mk[i] 表示 i i i 这个AC自动机上节点是否为某个不幸运的数结尾。

仔细读题会发现:模式串中含有 0 0 0 前置,而文本串不能以 0 0 0 开头。所以有(所有数组下标从 1 1 1 开始, 1 ≤ n [ 1 ] ≤ 9 1\le n[1]\le 9 1n[1]9,因为 c h [ 1 ] [ i ] ch[1][i] ch[1][i] 会有重复所以用 + + ++ ++ 而非 = 1 =1 =1):

d p [ 1 ] [ c h [ 1 ] [ i ] ] [ 0 ] + + ( 1 ≤ i < n [ 1 ] , m k [ c h [ 1 ] [ i ] ] ! = 1 ) dp[1][ch[1][i]][0]++(1\le i<n[1],mk[ch[1][i]]!=1) dp[1][ch[1][i]][0]++(1i<n[1],mk[ch[1][i]]!=1)

然后如果上式 i i i n [ 1 ] n[1] n[1],那么这个字符串的下一位就会受到 n [ 2 ] n[2] n[2] 大小的限制,所以有:

d p [ 1 ] [ c h [ 1 ] [ n [ 1 ] ] ] [ 1 ] + + ( m k [ c h [ 1 ] [ n [ 1 ] ] ] ! = 1 ) dp[1][ch[1][n[1]]][1]++(mk[ch[1][n[1]]]!=1) dp[1][ch[1][n[1]]][1]++(mk[ch[1][n[1]]]!=1)

综上,有代码:

for(int i=1;i<=w[1]-'0';i++)
	if(!mk[ch[1][i]])//不能选到不幸运的子串
		(f[1][ch[1][i]][i==w[1]-'0']+=1)%=mod; //Orz

为了避免算上首位为 0 0 0 的文本串,上面的代码没有 d p [ 1

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值