哇乍一看这题怎么这么水啊,但是我看到了最后一行的时候才发现其实不然(滑稽)
它要求的答案是所有数的平方和!!!
首先裸裸的数位 Dp 求出了满足条件的数的个数(定义 dp [ 位数 ] [ 每位和%7 ] [ 数值%7 ]),记为 Cnt,那么我们现在考虑如何将答案给搞出来吧!
我们可以利用 Dfs 的步骤,考虑将第 Dep 位的答案用 Dep 减1位更新
首先很好更新的是前 Dep 位的所有合法数字和,我们考虑所有数字的和一定可以拆分成:
所以显然第 Dep 位数为 i 时对于答案的贡献就是 i *(Dfs 下一位所得到的合法数的个数)* (10 的 Dep 次方),记为 Sum
其次考虑如何更新 Dep 位对于平方和的贡献啦!首先前 Dep 位组成的一个数的平方一定是:
由于我们只用加上 i 对当前位的贡献,所以这个时候我们只用关心与当前位 i 有关的东西, 管都不用管,直接展开换成 就好啦!
那么 Cnt 个数呢?这个时候 Dep 位 的贡献就多了 Cnt 倍,对吧,所以
推就是了
AC码:
# include <bits/stdc++.h>
const long long mod = 1e9 + 7 ;
long long powx [ 30 ] , dig [ 30 ] , x , y ;
int T ;
struct Node {
long long cnt , sum , sqs ;
}
dp [ 25 ] [ 20 ] [ 20 ] ;
Node dfs ( int dep , int res , int num , int lim ) {
if ( dep == 0 ) {
Node tmp = ( Node ) { 0 , 0 , 0 } ;
if ( num != 0 && res != 0 ) tmp . cnt = 1 ;
return tmp ;
}
if ( ! lim && dp [ dep ] [ res ] [ num ] . cnt != - 1 ) return dp [ dep ] [ res ] [ num ] ;
long long i = lim ? dig [ dep ] : 9 ;
Node ans ;
ans . cnt = ans . sum = ans . sqs = 0 ;
for ( ; i >= 0 ; i -- ) {
if ( i != 7 ) {
Node tmp = dfs ( dep - 1 , ( res * 10 + i ) % 7 , ( num + i ) % 7 , lim && i == dig [ dep ] ) ;
ans . cnt = ( ans . cnt + tmp . cnt ) % mod ;
ans . sum = ( ( ans . sum + ( i * powx [ dep - 1 ] % mod * tmp . cnt ) % mod ) % mod + tmp . sum ) % mod ;
ans . sqs = ( ( ans . sqs + tmp . sqs + ( 2 * i * powx [ dep - 1 ] % mod * tmp . sum ) % mod ) % mod + ( i * powx [ dep - 1 ] % mod * tmp . cnt % mod * powx [ dep - 1 ] % mod * i % mod ) % mod ) % mod ;
}
}
if ( ! lim ) dp [ dep ] [ res ] [ num ] = ans ;
return ans ;
}
long long solve ( long long x ) {
memset ( dp , - 1 , sizeof ( dp ) ) ;
int cnt = 0 ;
while ( x ) {
dig [ ++ cnt ] = x % 10 ;
x /= 10 ;
}
return dfs ( cnt , 0 , 0 , 1 ) . sqs ;
}
void init ( ) {
powx [ 0 ] = 1 ;
for ( int i = 1 ; i <= 19 ; i ++ )
powx [ i ] = ( 1ll * powx [ i - 1 ] * 10 ) % mod ;
}
int main ( ) {
init ( ) ;
scanf ( "%d" , & T ) ;
for ( int i = 1 ; i <= T ; i ++ ) {
std :: cin >> x >> y ;
std :: cout << ( ( solve ( y ) - solve ( x - 1 ) ) % mod + mod ) % mod << std :: endl;
}
return 0 ;
}