洛谷P3455

 1 /*
 2   题意:1<=x<=b<=5e4 1<=y<=d<=5e4 求gcd(x,y)=k的对数
 3   思路:莫比乌斯反演+整除分块
 4   时间:2018.07.11
 5 */
 6 #include <bits/stdc++.h>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int MAXN=100005;
11 const LL MOD7 = 1e9+7;
12 
13 int check[MAXN];
14 int prime[MAXN];
15 int mu[MAXN];
16 int fmu[MAXN];
17 int cnt;
18 
19 void Mobius()
20 {
21     cnt=0;
22     mu[1]=1;
23     for (int i=2;i<MAXN;++i)
24     {
25         if (!check[i])
26         {
27             prime[cnt++]=i;
28             mu[i]=-1;
29         }
30         for (int j=0;j<cnt&&i*prime[j]<MAXN;++j)
31         {
32             check[i*prime[j]]=1;
33             if (i%prime[j]==0)
34             {
35                 mu[i*prime[j]]=0;
36                 break;
37             }
38             else
39             {
40                 mu[i*prime[j]]=-mu[i];
41             }
42         }
43     }
44     for (int i=1;i<MAXN;++i) fmu[i] = fmu[i-1] + mu[i];
45 }
46 
47 int main()
48 {
49 #ifndef ONLINE_JUDGE
50     //freopen("test.txt","r",stdin);
51 #endif // ONLINE_JUDGE
52     Mobius();
53     LL a,b,c,d,k,ans,ans2;
54     int T;
55     scanf("%d",&T);
56     for (int t=1;t<=T;++t)
57     {
58         scanf("%lld%lld%lld",&b,&d,&k);
59         // printf("b=%lld\td=%lld\tk=%lld\n",b,d,k);
60         if (k==0)
61         {
62             printf("0\n",t);
63             continue;
64         }
65         ans=0;
66         ans2=0;
67         b/=k,d/=k;
68         LL sup = min(b,d);
69         for (LL i=1,j;i<=sup;i=j+1)
70         {
71             j = min(b/(b/i), d/(d/i));
72             ans += (fmu[j]-fmu[i-1]) * (b/i) * (d/i);
73             // ans2 += mu[i] * (sup/i) * (sup/i);
74         }
75         // ans -= ans2/2;
76         printf("%lld\n", ans);
77     }
78     return 0;
79 }

猜你喜欢

转载自www.cnblogs.com/LeeSongt/p/9297093.html