count_prime
Time Limit: 1000ms
Memory Limit: 65536KB
Description
给定你一个数n,请你统计出在[a,b]这个区间中和n互质的数的个数。
两个数互质当且仅当他们除了1之外没有其他的公共因子或者他们最大的公共因子是1。1和任何数是互素的。
Input
第一行输入一个整数T(1 <= T <= 100),表示T组测试数据。
接下来T行,每行3个整数a,b,n(1 <= a <=b <=10^15, 1<= n <= 10^9),用空格隔开。
Output
输出一个整数表示和n互质的数的个数。
Sample Input
2
1 10 2
3 10 5
Sample Output
5
6
标准题解:
容斥原理、先对n分解质因数,分别记录每个质因数,那么所求区间内与某个质因数不互质的个数就是n/r(i),假设r(i)是r的某个质因子 假设只有三个质因子,总的不互质的个数应该为p1+p2+p3-p1p2-p1p3-p2p3+p1p2*p3, 及容斥原理,pi代表n/r(i),即与某个质因子不互质的数的个数,当有更多个质因子的时候,可以用状态压缩解决,二进制位上是1表示这个质因子被取进去了。如果有奇数个1就相加,反之则相减。
代码:
#include <iostream>
using namespace std;
long long int primeNum[1000];
long long int num = 0;
void findPrime(long long int a)
{
num = 0;
for(int i = 2; i * i <= a; i++)
{
if(a % i == 0)
{
primeNum[num] = i;
num++;
while(a%i == 0)
a = a / i;
}
}
if(a > 1)
{
primeNum[num] = a;
num++;
}
}
long long int hasaki(long long int n)
{
long long int que[10000],k,t=0,sum=0;
que[t]=-1;
t++;
for(long long int i=0;i<num;i++)
{
k=t;
for(long long int j=0;j<k;j++)
{
que[t]=que[j]*primeNum[i]*(-1);
t++;
}
}
for(int i=1; i<t;i++)
sum = sum + n/que[i];
return sum;
}
int main()
{
int t;
cin >> t;
while(t -- )
{
long long int a,b,n;
cin >> a >> b >> n;
findPrime(n);
long long int ans;
ans = b - hasaki(b) - (a-1 - hasaki(a-1));
cout << ans <<endl;
}
return 0;
}