• zoj 3233 容斥原理 + 双条件


    题目来源:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3490

    题意:  给出两个集合Y , N , 给出区间【low , high】 , 问在 这个区间有多少个这样的数,x ,  满足, 集合Y中至少一个数被x 整除, 且 集合 N中至少一个数不被x 整除。

    分析:两个条件

    Q1 :  集合Y中至少一个数被x 整除 , 满足这个条件的个数为 A;

    Q2 :  集合 N中至少一个数不被x 整除。 满足这个条件的个数为B

    集合 s = {1 ,2 ,....n} 中 满足 这两个条件的个数, 为 :  A ∩ B = A - (A- B) = A - (A ∩  ¬ B) 

    非B  表示,  满足 条件  集合N中 所有数被 x  整除的   , 这样 x 的个数。

    所以在 计算 每个节点的个数时 , 使用 这个函数

    LL cel(LL a, LL num){
    return num / a - num / LCM(a , lcm) ;
    }

    代码如下:

    using namespace std ;
    const double EPS = 1e-16 ;
    typedef long long LL ;
    const int Max_N =  505;
    const double inf = 1e10 ; // 这个 开小了 1e9 都WA了好几次
    int n , m;
    LL low , high , lcm  , a[Max_N] , b ;
    LL GCD(LL x, LL y){
        return y == 0 ? x : GCD(y , x % y) ;
    }
    LL LCM(LL x, LL y){ // 处理巧妙,防止越界
        LL g;
        g = GCD(x , y) ;
        if(x / g > high / y)
            return high + 1 ;
        return x / g * y ;
    }
    LL cel(LL a,  LL num){
        return num / a - num / LCM(a , lcm) ;
    }
    void dfs(int now , int Count , LL lcm_1 , LL &sum , LL num){
        lcm_1 = LCM(a[now] , lcm_1) ;
        if(Count & 1)
            sum += cel(lcm_1 , num);
        else sum -= cel(lcm_1 , num);
        for(int i = now + 1 ; i < n ; i++){
            dfs(i , Count +1 , lcm_1 , sum , num ) ;
        }
    }
    void ok(){
        LL sum1 = 0 ,sum2  = 0;
        int i;
        for(i = 0 ; i < n ;i++){
            dfs(i, 1 , a[i] , sum1 , high) ;
        }
        for(i = 0 ; i < n ;i++){
            dfs(i, 1 , a[i] , sum2 , low -1) ;
        }
        printf("%lld
    " , sum1 - sum2) ;
    }
    int main(){
        int i ;
        while(cin>>n >> m >> low >> high){
            lcm = 1 ;
            if(n == 0 && m ==0 && low == 0 && high == 0) break ;
            for(i = 0 ; i < n ; i++)
                scanf("%lld" , &a[i]) ;
            for(i = 0 ; i < m ; i++){
                scanf("%lld" , &b) ;
                lcm = LCM(lcm , b) ;
            }
            ok() ;
        }
    }
  • 相关阅读:
    loj#6433. 「PKUSC2018」最大前缀和(状压dp)
    PKUWC2019游记
    10. Regular Expression Matching
    9. Palindrome Number
    8. String to Integer (atoi)
    7. Reverse Integer
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    4. Median of Two Sorted Arrays
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3731852.html
Copyright © 2020-2023  润新知