• BZOJ 1853: [Scoi2010]幸运数字


    1853

    思路:

    容斥原理

    先预处理出所有的幸运数字,然后去重,然后用容斥原理求

    有一个优化,从大的开始求lcm,如果大于b了就不用枚举了,这是因为两个大于1e5的乘起来就会

    所以最后枚举的子集只用在小于1e5中考虑就行了,小于1e5只有很少

    还有要用unsigned long long,不然会溢出

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL unsigned long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
     
    const int N = 4000;
    LL a, b, ans = 0;
    LL Luck[N], luck[N];
    LL lcm(LL a, LL b) {
        return a / __gcd(a, b) * b;
    }
    void dfs(LL sum, int cnt, int pos) {
        if(sum > b) return ;
        if(pos == -1) {
            if(cnt == 0) return ;
            if(cnt&1) ans += b/sum - a/sum;
            else ans -= b/sum - a/sum;
            return ;
        } 
        dfs(sum, cnt, pos-1);
        dfs(lcm(sum, luck[pos]), cnt+1, pos-1);
    } 
    int main() {
        scanf("%llu %llu", &a, &b);
        a--;
        int tot = 0;
        for (int l = 1; l <= 10; l++) {
            for (int i = 0; i < (1<<l); i++) {
                for (int j = l-1; j >= 0; j--) {
                    if(i&(1<<j)) Luck[tot] = Luck[tot] * 10 + 8;
                    else Luck[tot] = Luck[tot] * 10 + 6;
                } 
                tot++;
            }
        }
        int cnt = 0;
        for (int i = 0; i < tot; i++) {
            bool f = true;
            for (int j = 0; j < cnt; j++) {
                if(Luck[i] % luck[j] == 0) {
                    f = false;
                    break;
                }
            }
            if(f) luck[cnt++] = Luck[i];
        }
        dfs(1, 0, cnt-1);
        printf("%llu
    ", ans);
        return 0;
    } 
  • 相关阅读:
    2012的目标
    让顺丰快递给折腾了,昨晚发的快递,现在还没挪地方
    做的FM收音机终于交工,老婆验收完毕
    C语言宏定义使用技巧
    20棵树植树问题
    C简单实现动态2维数组
    运动量测试
    #pragma pack(n)的含义及其用法
    回调函数
    ubuntu 全局配置文件
  • 原文地址:https://www.cnblogs.com/widsom/p/9694280.html
Copyright © 2020-2023  润新知