注意lcm要用LL
先给一个样例
1
2
1 10
思路、其实这题就是问,给定一堆数,要求不能整除其任意一个的数字有多少个。
容辞 + lcm
dfs暴力枚举每一位选还是不选,一共n位。00010101010.
然后奇减偶加
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 15 + 20; int a[maxn]; int ans; int L, R, n; int did(LL val) { return (R / val) - ((L - 1) / val); } LL lcm(LL a, LL b) { return a / __gcd(a, b) * b; } void dfs(LL val, int has, int cur) { if (val > R) return; if (cur == n + 1) { if (!has) return; // cout << val << endl; if (has & 1) { ans -= did(val); } else ans += did(val); return; } // if (cur > n) return; dfs(lcm(val, a[cur]), has + 1, cur + 1); dfs(val, has, cur + 1); } void work() { scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); a[i] = lcm(a[i], 8); // a[i] *= 8; } // for (int i = 1; i <= n; ++i) { // cout << a[i] << " "; // } // cout << endl; scanf("%d%d", &L, &R); ///***debug**** // int ans1 = 0; // for (int i = L; i <= R; ++i) { // bool flag = true; // if (i % 8 != 0) continue; // for (int j = 1; j <= n; ++j) { // if (i % a[j] == 0) { // flag = false; // break; // } // } // if (flag) ans1++; // } // cout << ans1 << endl; ans = did(8); // cout << ans << endl; dfs(1, 0, 1); cout << ans << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
时间: 2024-10-14 09:40:17