数位dp,注意当出现次数大于限制次数的时候直接返回0,pos==0还不大于就返回1

f[pos][num][cnt] 表示第pos位,末尾数字为num,连续次数为cnt
如果下一位还是num,那么转移到dp(pos-1,num,cnt+1)
否则转移到dp(pos-1,i,1)
也就是说转移到新的数字 这个数字连续出现了一次。

最后注意答案算出来要加上mod再取余一次

#include <bits/stdc++.h>
using namespace std;
const int mod=20020219;
#define int long long
int book[20];
int f[20][20][20];
int a[11];
int dp(int pos,int num,int cnt,int flag)
{
    if(cnt>book[num]) return 0;
    if(pos==0) return 1;
    if(flag&&f[pos][num][cnt]!=-1) return f[pos][num][cnt];
    int x=flag?9:a[pos];
    int ans=0;
    for(int i=0;i<=x;i++)
    {
        if(i==num) ans=(ans+dp(pos-1,i,cnt+1,flag||i<x))%mod;
        else ans=(ans+dp(pos-1,i,1,flag||i<x))%mod;
    }
    if(flag) f[pos][num][cnt]=ans;
    return ans;
}
int cul(int x)
{
    int pos=0;
    while(x)
    {
        a[++pos]=x%10;
        x/=10;
    }
    return dp(pos,0,0,false);
}
signed main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(f,-1,sizeof(f));
        memset(a,0,sizeof(a));
        memset(book,0x3f3f3f3f,sizeof(book));
        int l,r,n;
        scanf("%lld%lld%lld",&l,&r,&n);
        while(n--)
        {
            int num,cnt;
            scanf("%lld%lld",&num,&cnt);
            book[num]=min(book[num],cnt);
        }
        printf("%lld\n",(cul(r)-cul(l-1)+mod)%mod);
    }
}