ABC338G 题解

ABC338G 题解

计数题,没有太多思维难度,就是麻烦。

显然 +* 是比较难搞的,应考虑子问题。

复杂度要求线性,考虑每个位置的贡献。

Case 1:只有数字

Ex: 1234

考虑 2 的贡献,枚举一下看看。

  • \(12=1\times 10+2\times1\)
  • \(123=1\times 100+2\times10+3\times1\)
  • \(1234=\dots\)
  • \(2=2\times1\)
  • \(23=2\times 10+3\times 1\)
  • \(234=\dots\)

2 贡献了 \(2\times 111=222\) 次。

引理:总贡献次数 \(=\) 左边 \(\times\) 右边

例如:122 贡献了 \(2\) 次,2342 贡献了 \(111\) 次,1234 中正好是 \(2\times111\) 次。

设当前是第 \(p\) 位,长度为 \(n\),则总贡献次数为 \(p\times\sum\limits_{i=0}^{n-p} 10^i\)

证明显然,请读者自行完成。

Case 2:只有数字 & +

Ex: 99+1234+999

仍然考虑 2 的贡献次数,请读者仿照 Case 1 自行枚举。

发现第一个加号前和第二个加号后的内容是不影响答案的,故可以只考虑两加号之间的部分,最后加上前后长度即可。

设当前位置、后面第一个加号位置为 \(s,t\),当前忽略加号的位置为 \(pd\),总数字量为 \(n\),则总贡献次数为
\(pd\times\left(\sum\limits_{i=0}^{t-s-1} 10^i+ (n-pd)\times10^{t-s-1}\right)\)

好长的式子

Case 3:数字 & + & *(原问题)

先解决算重复的问题。

比如 2*3 中,\(2\times3\) 只应该被计算一次,但如果计算贡献,会在 23 上分别统计一次,就算重了。

key:只在最后一个数上统计乘法答案(结合律)。

(当然你也可以在第一个数上计算,只不过从左到右扫,在最后统计更方便)

2*3 中,2 贡献 \(1\) 次,3 贡献 \(2+1=3\) 次。


Ex: 99+345*456*567*12+999

通过 Case 2 我们发现,可以把整个串用 + 号分割,每一小段单独考虑。

故统计 2 的答案,只需要看 345*456*567*12 这一部分,请读者自行枚举。

发现乘法对 2 的贡献就是345*456*567 的后缀贡献和,这是很容易 dp 计算的。具体说,就是每个数计算和,乘上后面的数,滚雪球。

\(\big[(3\times 100+4\times20+5\times3)\times 456+(4\times100+5\times20+6\times3)\big]\times 567 + \dots\)

加法的贡献和 Case 2 相同,不多赘述。

注意:乘法中非最后一个数的,向右只考虑乘号前、加号后的部分(反之亦然)!

例如 3 只考虑 345999,乘法部分不算。

小结

  • 分成 \(3\) 个子问题考虑。
  • 从简单开始枚举。
  • 考虑每个位置的贡献。
  • 分治(左右 & 符号分段)。
  • 相同的部分合并计算。
  • 乘法只算一次。

代码不难写,注意下标 & 取模的细节。

posted @ 2024-03-01 22:28  Cindy_Li  阅读(43)  评论(0)    收藏  举报