HDU 4507 吉哥系列故事——恨7不成妻(数位DP)

版权声明:没人会转的( ̄▽ ̄) https://blog.csdn.net/j2_o2/article/details/85259685
题目链接
题意

求一定区间内和7无关的数字的平方和。

思路

数位DP求以下三种东西
设数位DP当前位为now,下次搜索为i,后缀位为nt

  • cnt 与7无关数的个数,基础数位DP
  • sum 与7无关数的和,now.sum = (i*10^pos)*nt.cnt+nt.sum
  • q 与7无关数的平方和, n o w . q = ( i 1 0 p o s + n t . s u m ) 2 = i i 1 0 p o s 1 0 p o s + 2 i 1 0 p o s n t . s u m + n t . q now.q = (i*10^{pos}+nt.sum) ^2 = i*i*10 ^{pos}*10 ^{pos}+2*i*10 ^{pos}*nt.sum+nt.q

i i 1 0 p o s 1 0 p o s i*i*10 ^{pos}*10 ^{pos} 出现nt.cnt次需要额外×nt.cnt
2 i 1 0 p o s n t . s u m 2*i*10 ^{pos}*nt.sum 无需×nt.cnt,因为nt.sum已经将当前搜索i的后缀的全部求和
n t . q = n t . s u m n t . s u m nt.q = nt.sum*nt.sum 直接继承即可

代码
#include <stdio.h>
#include <string.h>

#define ll long long

struct Node
{
    ll cnt, sum, q, f;
    Node():cnt(0),sum(0),q(0),f(0){}
}dp[20][10][10];

ll num[20], mod = 1e9+7, de[20];

Node dfs(ll pos, ll limit, ll sum, ll now)
{
    if(pos == -1)
    {
        Node nt;
        if(sum && now) nt.cnt = 1;
        return nt;
    }
    if(!limit && dp[pos][sum][now].f) return dp[pos][sum][now];
    ll up = limit ? num[pos] : 9;
    Node nt, tmp;
    for(ll i = 0; i <= up; ++i)
    {
        if(i == 7) continue;
        nt = dfs(pos-1, limit&&i==up, (sum*10+i)%7, (now+i)%7);
        tmp.cnt += nt.cnt;
        tmp.cnt %= mod;

        tmp.sum += (nt.cnt*i%mod*de[pos]%mod+nt.sum)%mod;
        tmp.sum %= mod;

        tmp.q += (nt.q+2*nt.sum*(i*de[pos]%mod)%mod+(i*de[pos]%mod)*(i*de[pos]%mod)%mod*nt.cnt%mod)%mod;
        tmp.q %= mod;
    }
    tmp.f = 1;
    return limit ? tmp : dp[pos][sum][now] = tmp;
}

ll solve(ll n)
{
    ll pos = 0;
    while(n)
    {
        num[pos++] = n%10;
        n /= 10;
    }
    return dfs(pos-1, 1, 0, 0).q;
}

int main()
{
    ll t, l, r;
    memset(dp,0,sizeof(dp));
    de[0] = 1;
    for(ll i = 1; i <= 20; ++i) de[i] = 10*de[i-1]%mod;
    for(scanf("%lld",&t); t; --t)
    {
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/j2_o2/article/details/85259685