"SCOI2010" lucky number

Portal
Luogu

Problem-solving ideas

First constructed all the lucky numbers.
Then consider a lucky number will have much contribution.
For a number \ (X \) , which in the interval (\ [l, r]) \ number is a multiple of the \ (\ lfloor \ frac {r } {x} \ rfloor - \ lceil \ frac {l} X} {\ + rceil. 1 \) .
Then we just need a lucky number for each contribution can be counted once. . . . . ? ? ?
However, the answer is no.
Because the same number may be more lucky number of multiples, so we need to inclusion and exclusion of these lucky numbers lcm, empathy is to be removed before the other lucky number lucky number multiples, so good.

Details Notes

  • Pay attention to this problem may be some circumstances fried data range, long doubleto find out.

Reference Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define int long long 
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int LIM = 10000000000;
const int _ = 100002;

int n, vis[_], luck[_], l, r, ans;

inline void dfs1(int x) {
    if (x > LIM) return ;
    if (x != 0) luck[++n] = x;
    dfs1(x * 10 + 6), dfs1(x * 10 + 8);
}

inline void init() {
    dfs1(0);
    sort(luck + 1, luck + n + 1);
    for (rg int i = 1; i <= n; ++i)
        for (rg int j = i + 1; j <= n; ++j)
            if (luck[j] % luck[i] == 0) vis[j] = 1;
    int tmp = 0;
    for (rg int i = 1; i <= n; ++i)
        if (!vis[i]) luck[++tmp] = luck[i];
    n = tmp;
    sort(luck + 1, luck + n + 1, greater < int > ());
}

inline int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }

inline int f(int x) { return r / x - (l / x + (l % x != 0 ? 1 : 0)) + 1; }

inline void dfs(int x, int cnt, int Lcm) {
    if (x == n + 1) {
        if (Lcm != 1) ans += (cnt % 2 == 1 ? 1 : -1) * f(Lcm); return ;
    }
    dfs(x + 1, cnt, Lcm);
    long double _Lcm = 1.0 * Lcm / gcd(Lcm, luck[x]) * luck[x];
    if (_Lcm > r) return ;
    dfs(x + 1, cnt + 1, _Lcm);
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    init();
    read(l), read(r);
    dfs(1, 0, 1);
    printf("%lld\n", ans);
    return 0;
}

End Sahua \ (qwq \)

Guess you like

Origin www.cnblogs.com/zsbzsb/p/11779823.html