DarkBZOJ传送门
解析:
这个首先要分析一下,就算所有 2 , 9 2,9 2,9取遍, 1 0 10 10^{10} 1010中最多也只有 2 10 2^{10} 210个数,然后再打表把倍数删去,只有 466 466 466个。
而这 466 466 466个的 l c m lcm lcm的增长是非常快的,瞬间就会超过 R R R的范围,剪枝。
所以这道题可以容斥用 D F S DFS DFS大力搞一波,从大的数开始枚举会更快。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
ll l,r;
ll num[2000],cnt1,cnt2;
bool ban[2000];
inline void dfs(ll now){
if(now>r)return;
if(now)num[++cnt1]=now;
dfs(now*10+2);
dfs(now*10+9);
}
ll ans;
inline void dfs2(int pos,int f,ll L){
if(!pos){
if(L^1)ans+=f*(r/L-(l-1)/L);
return ;
}
dfs2(pos-1,f,L);
ll g=L/__gcd(L,num[pos])*num[pos];
if(g>r)return ;
dfs2(pos-1,-f,g);
}
signed main(){
scanf("%lld%lld",&l,&r);
dfs(0);
sort(num+1,num+cnt1+1);
for(int re i=1;i<=cnt1;++i){
if(ban[i])continue;
num[++cnt2]=num[i];
for(int re j=i+1;j<=cnt1;++j)if(num[j]%num[i]==0)ban[j]=true;
}
dfs2(cnt2,-1,1);
cout<<ans;
return 0;
}