参考学习:
https://blog.csdn.net/HowardEmily/article/details/78199037
https://blog.csdn.net/codeswarrior/article/details/81541972
O( n )筛法函数:
void init(){ memset(prime,0,sizeof(prime)); memset(mu,0,sizeof(mu)); memset(vis,0,sizeof(vis)); mu[1] = 1; cnt = 0; for(int i = 2; i < maxn; i++){ if(!vis[i]){ prime[cnt++] = i; mu[i] = -1; } for(int j = 0; j < cnt && i * prime[j] < maxn; j++){ vis[i*prime[j]] = 1; if(i % prime[j]) mu[i*prime[j]] = -mu[i]; else{ mu[i*prime[j]] = 0; break; } } } }
HDU 1695 GCD 反演经典入门:
http://acm.hdu.edu.cn/showproblem.php?pid=1695
Ac code:
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define LL long long 4 using namespace std; 5 typedef long long ll; 6 const int maxn = 1e5+7; 7 bool vis[maxn]; 8 int prime[maxn],mu[maxn]; 9 int cnt; 10 void init(){ 11 memset(prime,0,sizeof(prime)); 12 memset(mu,0,sizeof(mu)); 13 memset(vis,0,sizeof(vis)); 14 mu[1] = 1; 15 cnt = 0; 16 for(int i = 2; i < maxn; i++){ 17 if(!vis[i]){ 18 prime[cnt++] = i; 19 mu[i] = -1; 20 } 21 for(int j = 0; j < cnt && i * prime[j] < maxn; j++){ 22 vis[i*prime[j]] = 1; 23 if(i % prime[j]) mu[i*prime[j]] = -mu[i]; 24 else{ 25 mu[i*prime[j]] = 0; 26 break; 27 } 28 } 29 } 30 } 31 int main(){ 32 init(); 33 int T_case; 34 int a, b, c, d, k; 35 LL ans1 = 0, ans2 = 0; 36 scanf("%d", &T_case); 37 for(int Case = 1; Case <= T_case; Case++){ 38 ans1 = 0; ans2 = 0; 39 printf("Case %d: ", Case); 40 scanf("%d %d %d %d %d", &a, &b, &c, &d, &k); 41 if(b < k || d < k || k == 0){ 42 puts("0"); 43 continue; 44 } 45 b = b/k; 46 d = d/k; 47 int len = min(b, d); 48 for(int i = 1; i <= len; i++){ 49 ans1 += (LL)mu[i]*(b/i)*(d/i); 50 } 51 for(int i = 1; i <= len; i++){ 52 ans2 += (LL)mu[i]*(len/i)*(len/i); 53 } 54 printf("%lld ", ans1-ans2/2); 55 } 56 return 0; 57 }