Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.
Yoiu can assume that a = c = 1 in all test cases.
Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
2
1 3 1 5 1
1 11014 1 14409 9
Case 1: 9
Case 2: 736427
第一个区间:[1,2,...,b/k] 第二个区间:[b/k+1,b/k+2,...,d/k]
读第一个区间我们只要利用欧拉函数求质因数的个数即可,第二个区间我们任取x,
要求[1,2,...,b/k]中所有与x互质的数的个数,这里我们用到容斥原理:先将x质因数分解,
求得[1,2,...,b/k] 里所有能被x的质因数整除的数的个数,然后用b/k减去即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define N 100006 6 #define ll long long 7 ll a,b,c,d,k; 8 ll fac[N]; 9 ll eular(ll n) 10 { 11 ll res=1; 12 for(ll i=2;i*i<=n;i++) 13 { 14 if(n%i==0) 15 { 16 n/=i,res*=i-1; 17 while(n%i==0) 18 { 19 n/=i; 20 res*=i; 21 } 22 } 23 } 24 if(n>1) 25 res*=n-1; 26 return res; 27 } 28 ll solve() 29 { 30 ll ans=0; 31 for(ll i=b+1;i<=d;i++) 32 { 33 ll n=i; 34 ll num=0; 35 ll cnt=0; 36 for(ll j=2;j*j<=n;j++) 37 { 38 if(n%j==0) 39 { 40 fac[num++]=j; 41 while(n%j==0) 42 { 43 n/=j; 44 } 45 } 46 } 47 if(n>1) fac[num++]=n; 48 49 for(ll j=1;j<(1<<num);j++) 50 { 51 ll tmp=1; 52 ll sum=0; 53 for(ll k=0;k<num;k++) 54 { 55 if((1<<k)&j) 56 { 57 tmp*=fac[k]; 58 sum++; 59 } 60 } 61 if(sum&1) cnt+=b/tmp; 62 else cnt-=b/tmp; 63 } 64 ans=ans+b-cnt; 65 } 66 return ans; 67 } 68 int main() 69 { 70 int t; 71 int ac=0; 72 scanf("%d",&t); 73 while(t--) 74 { 75 printf("Case %d: ",++ac); 76 scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k); 77 if(k==0) 78 { 79 printf("0\n"); 80 continue; 81 } 82 if(b>d) 83 swap(b,d); 84 b/=k; 85 d/=k; 86 //printf("---%d %d\n",b,d); 87 ll ans=0; 88 for(ll i=1;i<=b;i++) 89 { 90 ans+=eular(i); 91 } 92 //printf("-%d\n",ans); 93 ans=ans+solve(); 94 printf("%I64d\n",ans); 95 } 96 return 0; 97 }