• 由于r,l比较大,直接long long,不开long long 见祖宗
  • 用arr存储幸运数字,下标从1开始,感觉这题没用DFS就是用了一个递归,依次枚举出在数据范围内所有的数,然后排个序
  • 再二分查找,查出大于等于l,r的幸运数字中最小数数的下标ll,rr;
  • 依次枚举l,r中的数肯定会超时,枚举arr中ll,rr区间就行了,需要注意的是,当处理最后一个数时,需要min(arr[i],r),Q-Q,比如r=442,但arr[rr]=444,直接加(arr[i]-x+1)*arr[i]是不行的,因为区间里没那么多数,(这儿卡了好久孱弱 @-@)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10;
LL arr[N],cnt=0;
LL l,r;
void dfs(LL t){
    if(t>10*r) return ;
    arr[cnt++]=t;
    LL x,y;
    x=t*10+4,y=t*10+7;
    dfs(x),dfs(y);
}
int find_l(int ll,int rr,int x){
    while(ll<rr){
        int mid=(ll+rr)/2;
        if(arr[mid]>=x) rr=mid;
        else ll=mid+1;
    }
    return ll;
}
int main(){
    scanf("%d%d",&l,&r);
    dfs(0);
    sort(arr,arr+cnt);
    int ll,rr;
    ll=find_l(1,cnt-1,l);
    rr=find_l(1,cnt-1,r);
    LL sum=0,x=l;
    for(int i=ll;i<=rr;i++){
        sum+=(min(arr[i],r)-x+1)*arr[i];//注意min(arr[i],r),最后一个数,要注意边界情况
        x=arr[i]+1;
    }
    cout<<sum;
    return 0;
}