SP3871 GCDEX - GCD Extreme
本题解参考这里
积性函数及筛法参考这里
欧拉反演参考这里
思路:
代码:
#include<bits/stdc++.h> using namespace std; #define int long long #define pb push_back const int maxn = 1e6 + 10; const int mod = 1e9 + 7; using namespace std; int f[maxn] , g[maxn] , low[maxn] , vis[maxn] , prime[maxn] , k[maxn];//low->最小值因子(带指数) int cnt = 0; void init() { low[1] = g[1] = 1; for(int i = 2 ; i <= maxn - 10 ; i ++){ if(!vis[i]){ vis[i] = 1 , low[i] = i , g[i] = 2 * i - 1 , prime[++ cnt] = i , k[i] = 1; } for(int j = 1 ; j <= cnt && prime[j] * i < maxn ; j ++){ vis[prime[j] * i] = 1; if(i % prime[j] == 0){///即 gcd(i , prime[j]) = p1 low[i * prime[j]] = low[i] * prime[j];/// if(low[i] == i){///是否 是p^k k[prime[j] * i] = k[i] + 1; g[i * prime[j]] = (k[i * prime[j]] + 1) * i * prime[j] - k[i * prime[j]] * i; } else{ g[i * prime[j]] = g[i / low[i]] * g[low[i] * prime[j]]; } break; } else{ g[i * prime[j]] = g[i] * g[prime[j]]; low[i * prime[j]] = prime[j];//prime[j] < p1 } } } f[1] = 1; for(int i = 2 ; i <= maxn - 10 ; i ++) { f[i] = f[i - 1] + 2 * g[i] - i; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; init(); while(cin >> n && n != 0) { // debug(f[n]); cout << (f[n] - (n * (n + 1) / 2)) / 2 << '\n'; } return 0; }