原题链接:
HDU:点我QωQ
题意简述
定义一个正整数和 7 7 7有关,满足以下三个之一:
- 某一位是 7 7 7
- 数位和是 7 7 7的倍数
- 原数是 7 7 7的倍数
那么就和 7 7 7有关。给定 Q Q Q和 Q Q Q个区间 [ l , r ] [l,r] [l,r],请求出 l , r l,r l,r里面和 7 7 7无关的数的平方和。
数据
输入
第一行是一个 Q ( Q < = 50 ) Q(Q<=50) Q(Q<=50)
接下来 Q Q Q行每行两个正整数 l , r ( 1 < = l , r < = 1 e 18 ) l,r(1<=l,r<=1e18) l,r(1<=l,r<=1e18)
输出
对于每个询问,输出答案。
样例
输入
3
1 9
10 11
17 17
输出
236
221
0
思路
写数位 D P DP DP最容易的事情就是写挂,真的。。。
我们先来设 d p dp dp状态。一开始我状态设多了,导致我转移都不会转移。。。来考虑几个状态,我们看看要不要:
- 位数:这个显然要用
- 首位:重要么?这个题中,如果我们要找和 7 7 7无关的,那么数位中肯定没有 7 7 7。在数位方面,我们只要保证这一点即可。为了保证这一点,我们只要在循环的时候不去搜 7 7 7即可。所以首位不用存。
- 有没有 7 7 7:同理,也不用。
- 位数和膜 7 7 7的余数:显然需要
- 原数膜 7 7 7的余数:同理,需要。
所以就是三维, d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示长度为 i i i,位数和余数是 j j j,原数余数是 k k k。
当然,一个 d p dp dp的答案还不能就是一个数:平方和。我们在推转移式子的时候,我们会发现:我们也要维护好满足条件的个数和一次方和。这个也不是不能维护,所以我们考虑打个结构体,都维护上。
然后这个 d p dp dp是干啥的呢?用来记忆化搜索的。搜索时候的状态,也就是长度,位数和余数,原数余数。然后我们现在设长度是 p o s pos pos,当前已经确定的位(有 c n t − p o s + 1 cnt-pos+1 cnt−pos+1位)的数字和膜 7 7 7是 s t a t e state state,当前已经确定的数膜 7 7 7的余数 r r r。
然后,转移的时候这么转移:
- 枚举下一位 i i