2393: Cirno的完美算数教室
Time Limit: 10 Sec Memory Limit: 128 MB
Description
~Cirno发现了一种baka数,这种数呢~只含有2和⑨两种数字~~
现在Cirno想知道~一个区间中~~有多少个数能被baka数整除~
但是Cirno这么天才的妖精才不屑去数啦
只能依靠聪明的你咯。
Input
一行正整数L R( 1 < L < R < 10^10)
Output
一个正整数,代表所求的答案
Sample Input
1 100
Sample Output
58
同【bzoj1853】[Scoi2010]幸运数字
大概是容斥的暴力。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 3000
using namespace std;
typedef long long ll;
ll L, R, a[maxn];
int cnt;
void prepare_baka(ll now){
if(now > R)return;
if(now)a[++ cnt] = now;
prepare_baka(now * 10 + 2);
prepare_baka(now * 10 + 9);
}
ll ans;
ll GCD(ll a, ll b){return !b ? a : GCD(b, a % b);}
void solve(const ll& k, int pos, int choose_num, ll now){
if(choose_num & 1)ans += k / now;
else if(choose_num)ans -= k / now;
for(int i = pos; i; i --){
ll lcm = a[i] / GCD(a[i], now) * now;
if(lcm <= k)solve(k, i - 1, choose_num + 1, lcm);
}
}
int main(){
scanf("%lld%lld", &L, &R);
prepare_baka(0);
sort(a + 1, a + 1 + cnt);
int tot = 0;
for(int i = 1; i <= cnt; i ++){
bool flag = true;
for(int j = i + 1; j <= cnt; j ++)
if(a[j] % a[i] == 0){flag = false;break;}
a[++ tot] = a[i];
}
cnt = tot;
solve(R, cnt, 0, 1);
ll tmp1 = ans;
ans = 0;
solve(L - 1, cnt, 0, 1);
printf("%lld\n", tmp1 - ans);
return 0;
}