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
解题思路:这道题如果用暴力方法直接做的话,一定会超时,因此要用到容斥原理来解决。
AC代码:
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
#define ll long long
int prime[100];
int m;
ll co_p(ll p)
{
ll sum=0,i,tmp;
int j,flag;
for(i=1;i<(ll)(1<<m);i++){
tmp=1,flag=0;
for(j=0;j<m;j++)
if(i&((ll)(1<<j))) //判断第几个因子目前被用到
flag++, tmp*=prime[j];
if(flag&1) sum+=p/tmp; //容斥原理,奇加偶减 ,跟tmp不互质的个数
else sum-=p/tmp;
}
return p-sum;
}
int main() //容斥原理
{
ll n,a,b,i,num;
int t,k=0;
scanf("%d",&t);
while(t--){
scanf("%I64d %I64d %I64d",&a,&b,&n);
m=0;
for(i=2;i*i<=n;i++) //注意此处是i*i<=n
if(n&&n%i==0){
prime[m++]=i;
while(n&&n%i==0)
n/=i;
}
if(n>1){
prime[m++]=n;
}
num=co_p(b)-co_p(a-1);
cout<<num<<endl;
}
return 0;
}