BZOJ1853/2393【容斥原理】

来源:互联网 发布:idea算法 编辑:程序博客网 时间:2024/06/15 23:20

如果一个幸运数是另外的幸运数的倍数.那么做容斥的时候就不需要考虑它了.

/* I will wait for you*/#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <algorithm>#include <iostream>#include <fstream>#include <vector>#include <queue>#include <deque>#include <map>#include <set>#include <string>#define make make_pair#define fi first#define se secondusing namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;const int maxn = 10010;const int maxm = 1010;const int maxs = 26;const int inf = 0x3f3f3f3f;const int P = 1000000007;const double error = 1e-9;inline ll read(){ll x = 0, f = 1;char ch = getchar();while (ch <= 47 || ch >= 58)f = (ch == 45 ? -1 : 1), ch = getchar();while (ch >= 48 && ch <= 57)x = x * 10 + ch - 48, ch = getchar();return x * f;}ll top, n, num[maxn], vis[maxn];ll gcd(ll a, ll b){return a ? gcd(b % a, a) : b;}ll dfs(int pos, int dir, ll sum){if (pos == top) {if (sum == 1)return 0;return (ll) (dir % 2 ? 1 : -1) * (n / sum);}if (vis[pos])return dfs(pos + 1, dir, sum);else {ll t = gcd(num[pos], sum), tmp = 0;tmp += dfs(pos + 1, dir, sum);if (sum / t <= n / num[pos])tmp += dfs(pos + 1, dir + 1, sum / t * num[pos]);return tmp;}}int main(){for (int i = 10; i >= 1; i--)for (int j = (1 << i) - 1; j >= 0; j--) {for (int k = i - 1; k >= 0; k--) {if ((1 << k) & j)(num[top] *= 10) += 8;else(num[top] *= 10) += 6;}top++;}for (int i = 0; i < top; i++)for (int j = i + 1; j < top; j++)if (num[i] % num[j] == 0)vis[i] = 1;ll l = read(), r = read(), ans = 0;n = l - 1, ans -= dfs(0, 0, 1);n = r, ans += dfs(0, 0, 1);printf("%lld\n", ans);return 0;}

0 0