• Co-prime(容斥原理+筛一个数的素因子)


    Co-prime

     HDU - 4135 

     

    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.

    InputThe 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 <= 10 15) and (1 <=N <= 10 9).OutputFor 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=30,那么找到30的素因子2 3 5,然后在区间[a,b]内用容斥原理找到2,3,5的倍数的个数ans,然后用区间长度减掉ans。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 const ll maxn=1e6+10;
     8 ll n,cnt,ans;
     9 ll prime[maxn];
    10 ll l,r;
    11 ll gcd(ll a,ll b)
    12 {
    13     if(b==0)
    14         return a;
    15     else
    16         return gcd(b,a%b);
    17 }
    18 ll Lcm(ll a,ll b)
    19 {
    20     return a*b/gcd(a,b);
    21 }
    22 ll get_prime(ll x)//如何找到x的素因子
    23 {
    24     for(ll i=2;i*i<=x;i++)
    25     {
    26         if(x%i)
    27             continue;
    28         while(x%i==0)
    29             x/=i;
    30         prime[cnt++]=i;
    31     }
    32     if(x!=1)            //如果x本身就是素数
    33         prime[cnt++]=x;
    34 }
    35 int casen;
    36 void dfs(ll m,ll th,ll now,ll step)
    37 {
    38 
    39     ll lcm=Lcm(prime[th],now);
    40     if(step&1)
    41     {
    42         ans+=m/lcm;
    43     }
    44     else
    45     {
    46         ans-=m/lcm;
    47     }
    48     for(ll i=th+1;i<cnt;i++)
    49         dfs(m,i,lcm,step+1);
    50 }
    51 int main()
    52 {
    53     scanf("%d",&casen);
    54     int ca=1;
    55     while(casen--)
    56     {
    57         ans=0;
    58         cnt=0;
    59         scanf("%lld%lld%lld",&l,&r,&n);
    60         get_prime(n);
    61 
    62         for(ll i=0;i<cnt;i++)
    63             dfs(l-1,i,prime[i],1);
    64         ll le=l-1-ans;
    65         //cout<<le<<endl;
    66         ans=0;
    67         for(ll i=0;i<cnt;i++)
    68             dfs(r,i,prime[i],1);
    69         ll ri=r-ans;
    70     //    cout<<ri<<endl; 
    71         printf("Case #%d: %lld
    ",ca++,ri-le);
    72     }
    73 }
  • 相关阅读:
    单元测试课堂练习
    软件工程个人作业02
    软件工程个人作业01
    构建之法提问
    大道至简-第七、八章-心得体会
    06-接口与继承 动手动脑及验证
    大道至简-第六章-心得体会
    随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中。
    大道至简-第五章-心得体会
    字符串加密
  • 原文地址:https://www.cnblogs.com/1013star/p/9885308.html
Copyright © 2020-2023  润新知