[数论][容斥原理]Co-prime
Posted lz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数论][容斥原理]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.
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\n",i,b-fun(b)-(a-1-fun(a-1))); } return 0; }
以上是关于[数论][容斥原理]Co-prime的主要内容,如果未能解决你的问题,请参考以下文章