Baidu Star 2019 · Programming Contest - 1003 preliminary round three

The meaning of problems:
seeking \ (\ sum_. 1} ^ {n-I = \ sum_ {J}. 1 ^ m = \ MU ({LCM (I, J)}) \) .

Ideas:
First, \ (LCM (I, J) = \ {ij of FRAC} {GCD (I, J)} \) , might have \ (lcm (i, j) \) squarefree, then there is \ (GCD (\ frac {i} {gcd (i, j)}, j) \) prime, so \ (\ mu (lcm (i , j)) = \ mu (i) \ mu (j) \ mu (gcd (i, J)) \) ; if \ (lcm (i, j) \) have a square factor, it does not affect the answer.
Note \ (mu \) values and quality factors related to the number, so we can directly "by" written "by."
Here is the time to push formula:

\[ \begin{aligned} &\sum_{i=1}^n \sum_{j=1}^m \mu(lcm(i,j))\\ =&\sum_{i=1}^n \sum_{j=1}^m \mu(i) \mu(j) \mu(gcd(i,j))\\ =&\sum_d\sum_i\sum_j\mu(i)\mu(j)\mu(d)\ (gcd(i,j)=d)\\ =&\sum_d\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor} \mu(id)\mu(jd)\mu(d)\ (gcd(i,j)=1)\\ =&\sum_d\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor} \mu(id)\mu(jd)\mu(d)\sum_{k|gcd(i,j)}\mu(k)\\ =&\sum_{d=1}^{min(n,m)}\sum_k\mu(k)\sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{dk}\rfloor}\mu(ikd)\mu(jkd)\mu(d) \end{aligned} \]
\(T=kd,T\leq min(n,m)\),则上式为:
\[ \sum_T\sum_{d|T}\mu(\frac{T}{d})\mu(d)\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{T}\rfloor}\mu(iT)\mu(jT) \]
之后对于每个\(T\)Pretreatment \ (\ sum_d \ mu (\ frac {T} {d}) \ mu (d) \) can, time complexity \ (O (nlogn) \) .
After part of the direct violence, the total time complexity is \ (O (Tnlogn) \) .

#include <bits/stdc++.h>
#define heyuhhh ok
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int T;
int mu[N], p[N];
ll sum[N];
bool chk[N];
void init() {
    mu[1] = 1;
    int cnt = 0, k = N - 1;
    for(int i = 2; i <= k; i++) {
        if(!chk[i]) p[++cnt] = i, mu[i] = -1;
        for(int j = 1; j <= cnt && i * p[j] <= k; j++) {
            chk[i * p[j]] = 1;
            if(i % p[j] == 0) {mu[i * p[j]] = 0; break;}
            mu[i * p[j]] = -mu[i];
        }
    }
    for(int i = 1; i <= k; i++) {
        for(int j = i; j <= k; j += i) {
            sum[j] += mu[i] * mu[j / i];
        }
    }
}
int n, m;
int main() {
#ifdef heyuhhh
    freopen("input.in", "r", stdin);
#else
    ios::sync_with_stdio(false); cin.tie(0);
#endif
    init();
    cin >> T;
    while(T--) {
        cin >> n >> m;
        ll ans = 0;
        for(int t = 1; t <= min(n, m); ++t) {
            ll s1 = 0, s2 = 0;
            for(int i = 1; i <= m / t; ++i) s1 += mu[i * t];
            for(int i = 1; i <= n / t; ++i) s2 += mu[i * t];
            ans += sum[t] * s1 * s2;
        }
        cout << ans << '\n';
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11408744.html