[CF628D] Magic Numbers

Description

给定 (d),如果一个数从高往低数第奇数位都是 (d),第偶数位都不是 (d),那么这个数称为 d-magic 数。

给定两个长度相等的数 (l,r)。求 ([l,r]) 中有多少个 d-magic 数,答案 (mod 10^9+7)(l,r) 的长度 (n le 2000)

Solution

转化为 (f(r)-f(l-1)) 的话还要做一下高精度减法,比较麻烦,所以我们就直接处理了。

对于每个状态,维护 (pos) 表示当前扫到从左到右的第 (pos) 位,(rem) 表示前 (i) 个数位构成的数的余数是 (rem),用两个标记 (tagl,tagr) 表示左边界和右边界是否已经与当前数分离。

转移过程显然是去枚举当前数位的所有可能取值,然后递归做下去。

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 2005;
const int mod = 1e9 + 7;

string a,b;
int m,d,f[N][N][2][2];

int solve(int pos,int rem,int tagl,int tagr)
{
    if(pos==a.length()) 
    {
        return !rem;
    }
    else 
    {
        if(~f[pos][rem][tagl][tagr]) 
        {
            return f[pos][rem][tagl][tagr];
        }
        else 
        {
            int ans=0;
            for(int now=0;now<=9;now++)
            {
                char c=now+'0';
                if((tagl || c>=a[pos]) && (tagr || c<=b[pos]) && (pos%2==(now==d)))
                {
                    ans+=solve(pos+1,(rem*10+now)%m,tagl||c>a[pos], tagr||c<b[pos]);
                    ans%=mod;
                }
            }
            return f[pos][rem][tagl][tagr]=ans;
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);

    cin>>m>>d>>a>>b;
    memset(f,-1,sizeof f);
    cout<<solve(0,0,0,0);
}
原文地址:https://www.cnblogs.com/mollnn/p/14016251.html