解题思路:求[a,b]区间内与n互质的数的个数,我们可以转化为[1,b]内与n互质的数的个数减去[1,a-1]内与n互质的数的个数
而要求[1,b]内与n互质的数的个数,我们可以很自然地想到容斥原理
求解区间[a,b]中与k互质的个数
首先对k进行质数分解,然后与这个因子GCD!=1则共有n/ki个
有计算重复的部分,因此利用 容斥原理: k1+k2+k3-k1*k2-.....求出与k不互质的个数,用总的减去即可
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
<pre name="code" class="cpp">#include<stdio.h> #include<iostream> #include<string.h> using namespace std; long long s[1020],k; void prime(long long m)//求一个数的素因子 { long long i; k=0; for(i=2;i*i<=m;i++) { if(m%i==0) { s[k++]=i; while(m%i==0) m/=i; //printf("%d\n",m); } } if(m>1) s[k++]=m; //printf("###\n"); } long long quc(long long m)//队列数组实现容斥原理 { long long p[10020],i,j,t=0,sum=0,z; p[t++]=-1; for(i=0;i<k;i++) { z=t; for(j=0;j<z;j++) { p[t++]=p[j]*s[i]*(-1); } } for(i=1;i<t;i++) sum+=m/p[i]; return sum; } int main() { long long n; scanf("%lld",&n); while(n--) { long long a,b,m,sum; scanf("%lld %lld %lld",&a,&b,&m); prime(m); sum=b-quc(b)-(a-1)+quc(a-1); printf("%lld\n",sum); } }
时间: 2024-10-09 06:01:53