• 容斥原理学习(Hdu 4135,Hdu 1796)


    题目链接Hdu4135

    Co-prime

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1412    Accepted Submission(s): 531


    Problem Description
    Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
    Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
     
    Input
    The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 1015) and (1 <=N <= 109).
     
    Output
    For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
     
    Sample Input
    2 1 10 2 3 15 5
     
    Sample Output
    Case #1: 5 Case #2: 10
    Hint
    In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.

    题意:求区间[a, b]内与n互质的数的个数。

    思路:如果某个数与n互质,那么这个数一定和n没有公共因子。所以题目就转化为有多少个数与n无公共因子。

    可以通过求区间内有多少个数与n存在公共因子来得到答案。筛去2的倍数,3的倍数,5的倍数。。。容斥就可以啦。

    Accepted Code:

     1 /*************************************************************************
     2     > File Name: 4135.c
     3     > Author: Stomach_ache
     4     > Mail: sudaweitong@gmail.com
     5     > Created Time: 2014年09月05日 星期五 16时33分45秒
     6     > Propose: 
     7  ************************************************************************/
     8 #include <cstdio>
     9 #include <vector>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 using namespace std;
    14 /*Let's fight!!!*/
    15 
    16 typedef long long LL;
    17 
    18 LL gcd(LL a, LL b) {
    19     if (!b) return a;
    20     return gcd(b, a % b);
    21 }
    22 
    23 LL cal(const vector<int> &var, const LL &n) {
    24       LL sz = var.size(), res = 0;
    25       for (LL i = 1; i < (1<<sz); i++) {
    26           int num = 0;
    27           for (LL j = i; j != 0; j >>= 1) if (j & 1) num++;
    28           LL lcm = 1;
    29           for (LL j = 0; j < sz; j++) {
    30               if ((i >> j) & 1) lcm = lcm / gcd(lcm, var[j]) * var[j];
    31               if (lcm > n) break;
    32           }
    33           if (num % 2 == 0) res -= n / lcm; 
    34           else res += n / lcm;
    35       }
    36 
    37       return res;
    38 }
    39 
    40 int main(void) {
    41     ios::sync_with_stdio(false);
    42     int T, cas = 1;
    43     cin >> T;
    44     while (T--) {
    45         LL a, b, n, x;
    46         cin >> a >> b >> n;
    47 
    48         vector<int> var;
    49         x = n;
    50         for (int i = 2; i * i <= x; i++) {
    51               if (x % i == 0) {
    52                 var.push_back(i);
    53                 while (x % i == 0) x /= i;
    54             }
    55         }
    56         if (x > 1) var.push_back(x);
    57 
    58         LL res = b - a + 1 - cal(var, b) + cal(var, a - 1);
    59         cout << "Case #" << cas++ << ": " << res << endl;
    60     }
    61 
    62     return 0;
    63 }

    题目链接Hdu1796

    How many integers can you find

    Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 4205    Accepted Submission(s): 1198


    Problem Description
      Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
    Input
      There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.
    Output
      For each case, output the number.
    Sample Input
    12 2 2 3
    Sample Output
    7
    和上题一样。。。
    Accepted Code:
    /*************************************************************************
        > File Name: 1796_dfs.cpp
        > Author: Stomach_ache
        > Mail: sudaweitong@gmail.com
        > Created Time: 2014年09月06日 星期六 08时28分01秒
        > Propose: 
     ************************************************************************/
    
    #include <cmath>
    #include <string>
    #include <cstdio>
    #include <fstream>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    /*Let's fight!!!*/
    
    typedef long long LL;
    int a[15], n, m;
    
    LL gcd(LL a, LL b) {
          if (!b) return a;
        return gcd(b, a % b);
    }
    
    void dfs(LL now, int num, LL lcm, LL &res) {
          lcm = lcm / gcd(lcm, a[now]) * a[now];
        if (num % 2 == 0) res -= n / lcm;
        else res += n / lcm;
        for (int i = now + 1; i < m; i++) 
              dfs(i, num + 1, lcm, res);
    }
    
    int main(void) {
          ios::sync_with_stdio(false);
        while (cin >> n >> m) {
              int cnt = 0;
            for (int i = 0; i < m; i++) {
                  int x;
                cin >> x;
                if (x > 0) a[cnt++] = x;
            }
            m = cnt;
            LL res = 0;
            n--;
            for (int i = 0; i < m; i++) {
                  dfs(i, 1, a[i], res);
            }
    
            cout << res << endl;
        }
    }
     
    
    //位运算实现
    /*************************************************************************
        > File Name: 1796.cpp
        > Author: Stomach_ache
        > Mail: sudaweitong@gmail.com
        > Created Time: 2014年09月05日 星期五 21时32分48秒
        > Propose: 
     ************************************************************************/
    
    #include <cmath>
    #include <string>
    #include <cstdio>
    #include <vector>
    #include <fstream>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    /*Let's fight!!!*/
    
    typedef long long LL;
    int a[12];
    
    LL gcd(LL a, LL b) {
        if (!b) return a;
        return gcd(b, a % b);
    }
    
    int main(void) {
        ios::sync_with_stdio(false);
        LL n, m;
        while (cin >> n >> m) {
            int d = 0;
            for (int i = 0; i < m; i++) {
                int x;
                cin >> x;
                if (x > 0 && x <= n) a[d++] = x;
            }
    
            n--;
            LL res = 0;
            for (LL i = 1; i < (1 << d); i++) {
                  int num = 0;
                for (LL j = i; j != 0; j >>= 1) num += j & 1;
                LL lcm = 1;
                for (LL j = 0; j < d; j++) {
                      if ((i >> j) & 1) {
                        lcm = lcm / gcd(lcm, a[j]) * a[j];
                        if (lcm > n) break;
                    }
                }
                if (num % 2 == 0) res -= n / lcm;
                else res += n / lcm;
            }
        
            cout << res << endl;
        }
        return 0;
    }
  • 相关阅读:
    【转载】JS中bind方法与函数柯里化
    计算机中位(bit), 字节(byte), 字(word)的关系
    MySQL 正则(Regular Expression) 邮箱(Email)
    eclipse remote system explorer operation
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    产品经理 写SQL
    DevOps Scrum Agile Tech Debt
    SpringMVC 集成 jackson,日志格式报错:org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value
    EDAS Serverless & Kubernetes SLB LVS Nginx
    阿里巴巴 开发者 工具 开源 社区
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3959117.html
Copyright © 2020-2023  润新知