设计好dp状态的含义,那么问题就很好解决了
dp[pos][sta]表示在数位pos上 之前所有数位满足的sta( 1 表示前面有一个"0" 2表示前面有"00" 3表示前面有"007" 当然是在没有前导0 且 当前pos位能取到最高位9的情况下)的方案数。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

typedef long long ll;
int b[4]={0,0,7,-1};
int a[20];//记录数位
ll dp[20][4];// sta 1 2 3->0 00 007
//dp用来存没有前导0且该位可取到最高位9时的方案数

ll dfs (int pos,int sta,bool lead,bool limit)//lead 1 有前导零 limit 1 当前可以取得最大值9
{
    if(pos==-1) return sta==3&&lead==0;//当有"007"且没有前导0
    //cout<<a[pos]<<" "<<sta<<endl;
    if(!limit&&!lead&&dp[pos][sta]!=-1) return dp[pos][sta]; //满足 没有前导 0且可以取到最高位9
    int up = limit ? a[pos]:9;
    ll tmp=0;
    for(int i=0;i<=up;i++)
    {
        //cout<<sta<<" "<<i<<endl;
        if(lead==0)//没有前导0
        {
            tmp+=dfs(pos-1,sta+(i==b[sta]),lead&&i==0,limit&&i==up);//i不可能等于-1 故sta加到3就不会再增加
        }
        else
        {
            tmp+=dfs(pos-1,0,lead&&i==0,limit&&i==up);//有前导0 则sta一直是0
        }
    }
    if(!limit&&!lead) dp[pos][sta]=tmp;
    return tmp;
}

ll cal (ll x)
{
    //x=  1234
    //pos=3210
    int cnt=0;
    while(x)
    {
        a[cnt++]=x%10;
        x/=10;
    }
    return dfs(cnt-1,0,1,1);
}

int main()
{
    int t;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    ll ans=0;
    while(t--)
    {
        ll l,r;
        scanf("%lld%lld",&l,&r);
        ans^=cal(r)-cal(l-1);
    }
    cout<<ans;
    return 0;
}