hdu4507吉哥系列故事——恨7不成妻 数位dp

来源:互联网 发布:diy设计装修软件 编辑:程序博客网 时间:2024/05/23 18:39
//(a1 + a2 + a3 + a4)^2 + (b1 + b2 + b3 + b4)^2
//=a1^2 + (a2+a3+a4)^2 + 2*a1*(a2+a3+a4) + b1^2 + 2*b1*(b1+b2+b3)
//每次dfs返回三个数,a,b,c
//a表示个数,b表示所有数的和,c表示所有数的平方和
//那么更新的ans.a += a;
//ans.b +=(b + i*temp_b*a)
//ans.c+=(c + (temp_b*i)^2*a + 2*(temp_b*i)*b)
//其中temp_b为当前数的数量级
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 20 ;
const int mod_m = 1e9 + 7;
struct node
{
   __int64 a , b , c;//a表示个数,b表示所有数的和,c表示所有数的平方和
} dp[maxn][10][10*maxn][2][2];
void equal(node &t1 ,node &t2)
{
    t1.a = t2.a;
    t1.b = t2.b;
    t1.c = t2.c;
}
int bit[maxn] ;
__int64 pow(__int64 a ,__int64 b)
{
    __int64 c = 1;
    while(b)
    {
        if(b & 1) c = ((c%mod_m) * (a%mod_m))%mod_m ;
        a = ((a%mod_m) * (a%mod_m))%mod_m ;
        b >>= 1;
    }
    return c;
}
node dfs(int pos,int mod ,int sum ,int flag ,int lim )
{
    if(dp[pos][mod][sum][flag][lim].a != -1)
    return  dp[pos][mod][sum][flag][lim];
    int num = lim ? bit[pos] : 9 ;
    struct node ans = {0,0,0};
    __int64 temp_c = (pow(10,pos-1) * pow(10 , pos-1)) % mod_m ;
    __int64 temp_b = pow(10 , pos-1) ;
    for(int i = 0;i <= num ;i++)
    {
        int mod_x = (mod*10 + i) % 7;
        int sum_x = sum + i ;
        int flag_x = flag;
        if(i == 7)
        flag_x = 1;
        if(pos == 1)
        {
            if(!flag_x && mod_x!= 0 && (sum_x%7) != 0)
            {
                ans.a += 1;
                ans.b += i;
                ans.c += i*i;
            }
           continue ;
        }
        struct node now = dfs(pos - 1, mod_x ,sum_x ,flag_x ,lim&&(i == num));
        __int64 a = now.a % mod_m;
        __int64 b = now.b % mod_m;
        __int64 c = now.c % mod_m;
        ans.c = (ans.c+c)%mod_m;
        ans.c = (ans.c + (((((a*temp_c)%mod_m)*(__int64)i)%mod_m)*i)%mod_m)%mod_m;
        ans.c = (ans.c + 2*(((b*temp_b)%mod_m)*(__int64)i)%mod_m)%mod_m;
        ans.b = (ans.b + ((__int64)i*((temp_b*a)%mod_m) + b)%mod_m) % mod_m;
        ans.a = (ans.a+a)%mod_m;
    }
    equal(dp[pos][mod][sum][flag][lim] ,ans) ;
    return ans;
}
__int64 solve(__int64 n)
{
    if(n==0)return 0;
    memset(dp , -1 ,sizeof(dp)) ;
    int len = 0;
    while(n)
    {
        bit[++len] = n%10;
        n/=10;
    }
    struct node now = dfs(len , 0 ,0 , 0 ,1 ) ;
    return now.c ;
}
int main()
{
    int T ;__int64 L , R;
    scanf("%d" ,&T) ;
    while(T--)
    {
        scanf("%I64d%I64d" ,&L ,&R) ;
        printf("%I64d\n" ,(solve(R) - solve(L-1)+mod_m)%mod_m) ;
    }
    return 0;
}







































0 0
原创粉丝点击