1. 程式人生 > >bzoj 1853 容斥 + 搜索

bzoj 1853 容斥 + 搜索

bsp fine rev clu 容斥 lag 所有 bits sin

思路:先把所有幸運數字找出來, 把沒有用的去掉,然後爆搜容斥,因為最多只會搜十幾個就超過限制了,

所以是可行的。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg
using namespace std;

const int N = 5000 + 7;
const int M = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1000000007; LL a[N], b[N], L, R, ans; int tot, top; void init(LL val) { if(val > R) return; if(val) a[++tot] = val; init(val * 10 + 6); init(val * 10 + 8); } void dfs(int p, int
cnt, LL lcm) { if(p > top) { if(cnt & 1) ans += R / lcm - (L - 1) / lcm; else if(cnt) ans -= R / lcm - (L - 1) / lcm; return; } dfs(p + 1, cnt, lcm); long long tmp = lcm / __gcd(b[p], lcm); if(1.0 * b[p] * tmp <= R) dfs(p + 1, cnt + 1, b[p] * tmp); }
int main() { scanf("%lld%lld", &L, &R); init(0); sort(a + 1, a + 1 + tot); for(int i = 1; i <= tot; i++) { bool flag = true; for(int j = 1; j <= top; j++) { if(a[i] % b[j] == 0) { flag = false; break; } } if(flag) b[++top] = a[i]; } reverse(b + 1, b + 1 + top); dfs(1, 0, 1); printf("%lld\n", ans); return 0; }

bzoj 1853 容斥 + 搜索