线性筛积性函数$g(x)$,具体看Yveh的题解:
http://sr16.com:8081/%e3%80%90bzoj2820%e3%80%91yy%e7%9a%84gcd/
#include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; const int N = 1E7 + 3; int getint() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0'; return k * fh; } bool np[N]; int g[N], mu[N], prime[N], sum[N]; void shai() { memset(np, 0, sizeof(np)); mu[1] = 1; g[1] = 0; sum[1] = 0; int num = 0; for(int i = 2; i <= 1E7; ++i) { if (!np[i]) {prime[++num] = i; mu[i] = - 1; g[i] = 1;} for(int j = 1; j <= num; ++j) { if (prime[j] * i > 1E7) break; np[prime[j] * i] = 1; if (i % prime[j] == 0) { mu[prime[j] * i] = 0; g[prime[j] * i] = mu[i]; break; } mu[prime[j] * i] = - mu[i]; g[prime[j] * i] = mu[i] - g[i]; } sum[i] = sum[i - 1] + g[i]; } } int main() { shai(); long long ret; int t, n, m; read(t); while (t--) { read(n); read(m); if (n > m) swap(n, m); ret = 0; for(int i = 1, la = 1; i <= n; i = la + 1) { la = min(n / (n / i), m / (m / i)); ret += (long long) (sum[la] - sum[i - 1]) * (n / i) * (m / i); } printf("%lld ", ret); } return 0; }
我确实弱==