• 「SCOI2010」幸运数字


    传送门
    Luogu

    解题思路

    首先构造出所有的幸运数字。
    然后考虑一个幸运数字会产生多少贡献。
    对于一个数 (x),它在区间 ([l,r]) 内的倍数的个数为 (lfloor frac{r}{x} floor - lceil frac{l}{x} ceil + 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
    ", ans);
    	return 0;
    }
    

    完结撒花 (qwq)

  • 相关阅读:
    HDU 5334 Virtual Participation(2015多校第四场)
    HDU 1754 I Hate It(线段树+单点更新)
    HDU 5308 I Wanna Become A 24-Point Master(2015多校第二场)
    linux下socket调试
    linux驱动之hello_world源码与编译
    那些年优秀的HTML5活动页面
    近期Responsive web design项目经验分享-高分辨率图片处理篇
    近期Responsive web design项目经验分享
    var foo= {} ;foo.method() 和 单例模式有什么区别
    Web程序设计
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/11779823.html
Copyright © 2020-2023  润新知