题目大意:
输入样例个数T,每个样例输入三个数a,b,n,求[a,b]之间与n互素的个数
基本思路:
互斥,想想这个:AUBUC=A+B+C-A∩B-A∩C-B∩C+A∩B∩C
fac存的是n的素因数que里存的是素因数的乘机以及符号,然后最后n/que得出的就是最后和n非互素的个数
代码如下:
#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; typedef long long ll; const int maxn = 1000000+10; ll que[maxn],fac[maxn],num; void divid(ll n) { num=0; for(ll i=2;i*i<=n;i++) { if(n%i==0) { while(n%i==0) n/=i; fac[num++]=i; } } if(n!=1) fac[num++]=n; } ll solve(ll n) { int k,t=0; ll ans=0; que[t++]=-1; for(ll i=0;i<num;i++) { k=t; for(ll j=0;j<k;j++) { que[t++]=-1*que[j]*fac[i]; } } for(ll i=1;i<t;i++) ans+=n/que[i]; return ans; } int main() { int T; scanf("%d",&T); int cas=0; while(T--) { ll a,b,n; scanf("%I64d%I64d%I64d",&a,&b,&n); divid(n); ll res=b-solve(b)-(a-1-solve(a-1)); printf("Case #%d: %I64d ",++cas,res); } return 0; }