zoukankan      html  css  js  c++  java
  • 容斥原理:HDU-4135Co-prime

    容斥原理公式:这里就需要用到容斥原理了,公式就是:n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5). 求的是多个重合区间的里面的数字个数。


    解题心得:

    1、一开始很傻很天真,使用遍历然后调用__gcd()来直接怼,但是肯定要超时啊,a,b的范围太大了。

    2、求一个数与另一个数是否互质还有一种算法,看这个数是否是另一个数的质因子的倍数(详细算法见:链接:求一个数的质因子),如果是则排除。这样就可以直接使用质因子来筛选就可以了,但是需要的是个数可以直接做除,这样使用的时间就大大的减少了。所以就可以将思路转换求a到b区间的互质数可以使用,0到b区间的互质数减去0-a-1区间的互质数。

    3、详细过程:先将一个数的质因子全部放在一个数组之中,看是否是质因子的倍数,这个时候就需要使用到容斥原理,因为不只是简单的将每个互质数组合的倍数减去就是了,有可能有的数重复减去了。


    题目:


    Co-prime
    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4738    Accepted Submission(s): 1894


    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}.

     

    Source
    The Third Lebanese Collegiate Programming Contest



    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6;
    int prim[maxn];//用来存储质因子
    int ch[maxn];//用来存储质因子的组合
    int n,T;
    long long a,b;
    
    //得到质因子
    void prim_num(int N)
    {
        T = 0;
        for(int i=2;i*i<=N;i++)
        {
            if(N%i == 0)
            {
                prim[T++] = i;
                while(N%i == 0)
                    N /= i;
            }
        }
        if(N != 1)
            prim[T++] = N;
    }
    
    long long Check(long long num)
    {
        memset(ch,0,sizeof(ch));
        ch[0] = -1;
        int t2 = 1;
        for(int i=0;i<T;i++)
        {
            int now;
            now = t2;
            //这个循环很重要它是得到的质因子的组合,仔细理解(顺序并不是和公式上面的顺序一样)
            for(int j=0;j<now;j++)
                ch[t2++] = ch[j]*prim[i]*(-1);
        }
    
        long long sum = 0;
        for(int j=1;j<t2;j++)
            sum = sum + num/ch[j];//虽然看起来都是加,但是有正有负,得到的就是最终的答案
        return sum;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        int z = t;
        while(t--)
        {
            scanf("%lld%lld%d",&a,&b,&n);
            prim_num(n);
            printf("Case #%d: ",z-t);
            long long now1 = b - Check(b);
            long long now2 = a-1 - Check(a-1);
            printf("%lld
    ",now1 - now2);
        }
    }
    



  • 相关阅读:
    算法分析及算法复杂度
    PAT乙级1023. 组个最小数(20 分)
    PAT乙级1022.D进制的A+B(20 分)
    PAT乙级1021.个位数统计(15 分)
    PAT乙级1019.数字黑洞(20 分)
    PAT乙级1018.锤子剪刀布 (20)(20 分)
    PAT乙级1017.A除以B(20 分)
    PAT乙级1016.部分A+B(15 分)
    tensorflow1.0 official basement
    机器学习---算法学习3
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107362.html
Copyright © 2011-2022 走看看