题目:
题意:
指定在 B B B进制下,给定一个区间 L ∼ R L\sim R L∼R,问该区间里的所有数的子串的和是多少
分析:
不得不吐槽下,这真是我做过最淦的 d p dp dp,人都给做没了
关于这题最重要的思想就是学会把以前答案对当前的贡献与新增数的贡献分开计算,在接下来的题解过程中将会反复运用到这一点
我肝了这题三四天了,每天改完比赛写完 b l o g blog blog就跑过来理解,搜到的真不容易看懂,就很烦,哪里没说清、没弄懂直接@我就 o k ok ok了,基本准时答疑
先定义一下哈, a a a表示数的个数(也就是从开始到现在有多少个数了); s l sl sl表示之前组成的数的位数的和; s s s表示到当前位置( a k a_k ak)时的后缀和,换句话来说,就是 ∑ i = 1 k ∑ j = i k a j \sum_{i=1}^k\sum_{j=i}^ka_j ∑i=1k∑j=ikaj; f f f表示的就是所有数的和,即答案
当然,还有数位 d p dp dp不可避免的上界问题,设 0 0 0表示前面的位置且包括当前位置的数正好等于最大值, 1 1 1表示小于
接下来我们对于上面列出的四个定义开始讨论转移方程式
在这之前还有一点要说明的,在转移时我们常常会将新填的数与之前已有的数分开,方便统计贡献与进行转移
a i , 0 : a_{i,0}: ai,0:因为一直是最大值,所以只会有一个数
a i , 1 : a_{i,1}: ai,1:假如新填的数单独出来,如 1 、 2 、 3 1、2、3 1、2、3,那么可以填 0 ∼ b − 1 0\sim b-1 0∼b−1;如果加到前面的数的后面,如果之前的数卡到了上界,我们能选择的只能是 0 ∼ z [ i ] − 1 ( 0\sim z[i]-1( 0∼z[i]−1(z[i]表示第i位最大值 ) ) ),对每个数都是如此,贡献就是 a i − 1 , 0 ∗ z [ i ] a_{i-1,0}*z[i] ai−1,0∗