- 由于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;
}