「SCOI2010」幸运数字

传送门
Luogu

解题思路

首先构造出所有的幸运数字。
然后考虑一个幸运数字会产生多少贡献。
对于一个数 \(x\),它在区间 \([l,r]\) 内的倍数的个数为 \(\lfloor \frac{r}{x} \rfloor - \lceil \frac{l}{x} \rceil + 1\)。
那么我们就只需要对每一个幸运数字算一次贡献即可。。。。。???
然而答案是否定的。
因为同一个数可能是多个幸运数字的倍数,所以我们就需要容斥这些幸运数字的lcm,同理在之前要去掉是其他幸运数字倍数的幸运数字,这样就好了。

细节注意事项

  • 注意一下这题可能会有一些炸数据范围的情况,long double 了解一下。

参考代码

#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;
}

完结撒花 \(qwq\)

原文地址:https://www.cnblogs.com/zsbzsb/p/11779823.html

时间: 2024-08-25 06:47:26

「SCOI2010」幸运数字的相关文章

LibreOJ #2013. 「SCOI2016」幸运数字

二次联通门 : LibreOJ #2013. 「SCOI2016」幸运数字 /* LibreOJ #2013. 「SCOI2016」幸运数字 树链剖分 + 线段树 + 线性基合并 没什么可说的 对原树进行树链剖分 然后建线段树 每个区间维护一段线性基 每次暴力把一段插入另一段中 最后线性基求最大即可 注意线性基求最大时一定是倒着枚举的 */ #include <cstdio> #include <iostream> const int BUF = 12312334; char Bu

bzoj1853【SCOI2010】幸运数字

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MB Submit: 1837  Solved: 673 [Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是"幸运号码"!但是这种"幸运号码"总是太

BZOJ 1853 【Scoi2010】 幸运数字

Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认 为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是"幸运号码"!但是这种"幸运号码"总是太少 了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种"近似幸运号码".lxhgww规定,凡是"幸运号 码"的倍数都是"近似幸

「SCOI2010」连续攻击游戏

传送门 Luogu 解题思路 二分图匹配,关键是建图. 如果我们naive地直接把每个武器的两个属性分为两部建图的话,显然是跑不了的. 我们考虑把每一个武器的属性向它连边:\(a_i \rightarrow i,b_i \rightarrow i\) 然后我们从属性这一部从小到大枚举,寻找增广路,直到找不到就输出答案. 细节注意事项 咕咕咕 参考代码 #include <algorithm> #include <iostream> #include <cstring>

1853: [Scoi2010]幸运数字[容斥原理]

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2405  Solved: 887[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,

【BZOJ1853/2393】[Scoi2010]幸运数字/Cirno的完美算数教室 DFS+容斥

[BZOJ1853][Scoi2010]幸运数字 Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”.lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”

AC日记——[SCOI2010]幸运数字 bzoj 1853

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2405  Solved: 887[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,

bzoj 1853: [Scoi2010]幸运数字 容斥

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 1170  Solved: 406[Submit][Status] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,

BZOJ-1853: [Scoi2010]幸运数字 (容斥原理)

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2947  Solved: 1096[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是"幸运号码"!但是这种"幸运号码"总是太少