在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。
现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。
额什么SCOI传统的数位DP
实际上就是容斥原理,因为出现了倍数关系
什么?你说他怎么会T
你先除掉倍数关系的
然后从大到小排序就完了。。。
主要是球LCM注意先除再乘
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
int L,R;
int Baka[3000];
int vis[3000];
int A[3000];
int cnt=0;
void DFS(int x,int sum){
if(sum>R)return;
if(sum)Baka[++cnt]=sum;
DFS(x+1,sum*10+2);
DFS(x+1,sum*10+9);
}
int ans=0;
int GCD(int x,int y){
while(y){
int tmp=y;
y=x%y;
x=tmp;
}
return x;
}
void Solve(int x,int sum,int flag){
if(sum<0||sum>R)return;
if(x==A[0]+1){
if(!sum)return;
ans=(ans+(R/sum-L/sum)*flag);
return;
}
int tmp;
if(!sum)tmp=A[x];
else tmp=sum/GCD(A[x],sum)*A[x];
Solve(x+1,tmp,flag*-1);
Solve(x+1,sum,flag);
}
bool cmp(int A,int B){
return A>B;
}
signed main(){
cin>>L>>R;
L--;
DFS(1,0);
sort(Baka+1,Baka+1+cnt);
for(int i=1;i<=cnt;++i){
if(!vis[i])A[++A[0]]=Baka[i];
for(int j=i+1;j<=cnt;++j){
if(Baka[j]%Baka[i]==0)vis[j]=1;
}
}
sort(A+1,A+1+A[0],cmp);
Solve(1,0,-1);
cout<<ans;
}