zoukankan      html  css  js  c++  java
  • [数论][容斥原理]Co-prime

    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互质的数的个数,可以转化为求[1,b]中与n互质的数的个数和[1,a]中与n互质的数的个数,最后相减即可。
    要求[1,b]中与n互质的数的个数,又可以转化为求[1,b]中与n不互质的数的个数,总数减去它便是互质的个数。
    要求[1,b]中与n不互质的数的个数,先要清楚怎样的数与n不互质:它必定是n的某个质因子的倍数。
    所以先将n分解质因子得到n的若干质因子{fac[1],fac[2],..},再求出[1,b]中有几个数fac[1]的倍数,几个数fac[2]的倍数,...,再根据容斥原理得到[1,b]中有几个数是{fac[1],fac[2],..}中某数的倍数。
    容斥原理:假设n有三个质因子{fac[1],fac[2],fac[3]},则[1,b]中为{fac[1],fac[2],fac[3]}中某数的倍数的数有f(b)=n/fac[1]+n/fac[2]+n/fac[3]-n/(fac[1]*fac[2])-n/(fac[1]*fac[3])-n/(fac[2]*fac[3])+n/(fac[1]*fac[2]*fac[3])个(奇加偶减)
     
    AC代码:
    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    
    ll factor[1000010];
    ll que[1000010];
    ll cnt;
    
    void get_factor(ll n){//分解质因数(模拟短除法)
      memset(factor,0,sizeof(factor));
      cnt=0;
      for(ll i=2;i*i<=n;i++){
        if(n%i==0){
            factor[++cnt]=i;
            while(n%i==0) n/=i;
        }
      }
      if(n>1) factor[++cnt]=n;
    }
    
    ll fun(ll n){//利用数组实现公式的计算
      memset(que,0,sizeof(que));
      ll k=0;
      for(ll i=1;i<=cnt;i++){
        que[++k]=factor[i];
        ll tmp=k;
        for(int j=1;j<=tmp-1;j++) que[++k]=que[tmp]*que[j]*(-1);
      }
      ll ret=0;
      for(ll i=1;i<=k;i++) ret+=n/que[i];
      return ret;
    }
    
    int main()
    {
        ll t;
        scanf("%lld",&t);
        ll a,b,n;
        for(ll i=1;i<=t;i++){
            scanf("%lld%lld%lld",&a,&b,&n);
            get_factor(n);
            printf("Case #%lld: %lld
    ",i,b-fun(b)-(a-1-fun(a-1)));
        }
        return 0;
    }
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    Java打印M图形(二维数组)——(九)
    Java调整JVM内存大小——(八)
    Java导出List集合到txt文件中——(四)
    Java读取Txt封装到对象中——(三)
    Java读取txt文件——(二)
    Java导出txt模板——(一)
    c# listview导出excel文件
    mfc 导出数据保存成excel和txt格式
    数据库日志删除重建方法
    HTTP POST请求的Apache Rewrite规则设置
  • 原文地址:https://www.cnblogs.com/lllxq/p/9015834.html
Copyright © 2011-2022 走看看