HDU 4135 Co-prime (容斥+分解质因子)

<题目链接>

题目大意:

  给定区间[A,B](1 <= A <= B <= 10 15)和N(1 <=N <= 10 9),求出该区间中与N互质的数的个数。

解题分析:

  将求区间[A,B]与N互质的数转化成求[1,B] 区间与N互质的个数  -  [1,A-1]中与N互质的个数。同时,因为直接求区间内与N互质的数不好求,我们从反面入手,求出与N不互质的数,借鉴埃筛的思想,我们先求出N的所有质因子,然后将这些质因子在区间内倍数的个数全部求出(即与N不互质的数),再用区间的总数减去这些不互质数的个数即可。但是,由于在求不互质的数的时候,存在重复的计算,所以我们利用容斥对重复计算的数进行处理。容斥处理有多重表现形式,DFS、队列、位运算均可进行容斥处理。

得到一个数的所有质因子:

for(ll i=2;i*i<=m;i++)
    if( m%i==0){   //得到m的所有的素因子
        vec.push_back(i);
        while(m%i==0)m/=i;
    }
if(m>1)vec.push_back(m);

位运算:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 typedef long long ll;
 8 vector<ll>vec;
 9 ll a,b,n;
10
11 ll solve(ll x,ll m){     //[1,x]区间内与m4互质的数的个数
12     vec.clear();
13     for(ll i=2;i*i<=m;i++) if( m%i==0){   //得到m的所有的素因子
14         vec.push_back(i);
15         while(m%i==0)m/=i;
16     }
17     if(m>1)vec.push_back(m);
18     ll sum=0,val,cnt;
19     for(ll i=1;i<(1<<vec.size());i++){   //枚举所有素因子的乘积组合,用二进制表示哪几个因子被用到
20         val=1,cnt=0;
21         for(ll j=0;j<vec.size();j++){
22             if(i & (1<<j)) {
23                 val*=vec[j],cnt++;
24             }
25         }
26         //容斥,奇加偶减
27         if(cnt & 1)sum+=x/val;    // x/tval为[1,x]内为tval的倍数的数的个数
28         else sum-=x/val;
29     }
30     return x-sum;      //[1,x]的总数减去1~X中各素数倍数的总数
31 }
32
33 int main(){
34     int T,ncase=0;scanf("%d",&T);while(T--){
35         scanf("%lld%lld%lld",&a,&b,&n);
36         ll ans=solve(b,n)-solve(a-1,n);
37         printf("Case #%d: %lld\n",++ncase,ans);
38     }
39 }

2019-02-09

原文地址:https://www.cnblogs.com/00isok/p/10357829.html

时间: 2024-10-11 22:31:57

HDU 4135 Co-prime (容斥+分解质因子)的相关文章

HDU 4497 GCD and LCM(分解质因子+排列组合)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4497 题意:已知GCD(x, y, z) = G,LCM(x, y, z) = L.告诉你G.L,求满足要求的(x, y, z)有多少组,并且要考虑顺序. 思路:如果L%G != 0显然不存在这样的(x, y, z),相反肯定存在.具体做法就是将L/G分解质因子,得到:L/G = P1^t1 * P2^t2 * ... * Pk^tk,我们来考虑任意一个因子Pi^ti,此时(x/G, y/G, z/

题解报告:hdu 4135 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

HDU 4135 Co-prime(容斥+数论)

Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5526    Accepted Submission(s): 2209 Problem Description Given a number N, you are asked to count the number of integers between A and B

HDU 4135 Co-prime(容斥:二进制解法)题解

题意:给出[a,b]区间内与n互质的个数 思路:如果n比较小,我们可以用欧拉函数解决,但是n有1e9.要求区间内互质,我们可以先求前缀内互质个数,即[1,b]内与n互质,求互质,可以转化为求不互质,也就是有除1的公因数.那么我们把n质因数分解,就能算出含某些公因数的不互质的个数.因为会重复,所以容斥解决.因为因数个数可能很多(随便算了一个20!> 2e18,所以质因数分解个数不会超过20个),我们可以用二进制来遍历解决. #include<set> #include<map>

HDU 4135 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 tha

UVA10780 - Again Prime? No Time.(分解质因子)

题目链接 题意:输入两个整数n和m,求最大的整数k使得m^k是n!的约数. 思路:m^k等于m的所有质因子的k次方的和,所以只要找到m中的质因子在n!中所能得到的最小的次方,就是k的值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int I

HDU 3641 Treasure Hunting (二分+分解质因子)

题目链接:HDU 3641 Treasure Hunting 题意:求X!%M==0中最小的的X.其中M=a1^b1*a2^b2*a3^b3.... 思路:求余为0想到整除,即分母的因子构成的集合是分子的因子构成的集合的子集.因子又想到,任何一个整数都可以分解成若干个素数相乘. 注意:题目数据很大,查到答案时二分. AC代码: #include<stdio.h> #include<string.h> #define ll __int64 bool Prime[210]; ll nu

分解质因子(个人模版)

分解质因子: 1 memset(prime,0,sizeof(prime)); 2 memset(num,0,sizeof(num)); 3 for(int i=2;i<=5000005;i++) 4 { 5 if(prime[i]==0) 6 { 7 for(int j=i;j<=5000005;j+=i) 8 { 9 int temp=j; 10 while(temp%i==0) 11 { 12 num[j]++; 13 temp/=i; 14 } 15 prime[i]=1; 16 }

poj3993Not So Flat After All(筛法素数+分解质因子)

题目链接: 啊哈哈,点我点我 题意: 题意是给出两个数字,然后有由一分解定理得,每个数可以分解成若干质因数的乘积,这样就可以在一个n维的坐标系下表示出这个点...比如给出50和24 因为24=2^3*3^1*5^0  而50=2^1*3^0*5^2那么这两个点就可以在一个3维德坐标系下表示出这两个点..24=(3,1,0)  50=(1,0,2)  那么共同拥有的维度就是3  而两个点在n维坐标系下的距离就是|3-1|+|1-0|+|0-2|=5,这样题意完全理解... 思路: 先筛出10000