Solution to a problem P1587 [US [NOI2016] cycle of]

JellyTHerSpace qwq

Knowledge Point: Mobius inversion multiplicative function Du teach sieve

nonsensePreface:

I love the ancient Ming, who wrote this solution to a problem I have been

Will the reader to ignoreDo things UnforgettableContent with strikethrough, thank eggplant.

This question itself is not difficult, but the formula derivation / Code process confusing more content, therefore, like meThis also blind nothing will immediately return cultural studies in relation to decommissioning of the spicy chicken waste wood konjac / kel / kel / kkIt will be in the debug onwasteNeedlessly time-consuming.

Therefore, when usually write the code, the code to develop good habits (for example: to determine common variable name, not easily modified; even very familiar with the function, but also carefully finished each line , etc.) is very important. Save the exam 10 minutes debug time, perhaps determine theYou did not go to collegeWhether the individual competition career will continue.

In addition, I wrote the purpose of this solution to a problem is not simply to tell you how this road ACwaterQuestion, but my thought process for everyone to share, so that we next encounter a similar purpose when the number of topics can be truly independent thinking . Therefore, we should not rely too much on the solution of the problemCodeReady-made formula, but the use of pen and paper on their own deduction .

PS: the first time \ (L_AT ^ EX \) write formulas, nice with qwq

So, start the topic:

Note: The default here we have a certain mastery of common arithmetical functions such as Mobius function, not repeat them.That you will not also learn number theory?

Is intended a topic: seeking \ (K \) under binary satisfy \ (1 \ leq x \ leq n, 1 \ leq y \ leq m, \) and \ (\ frac {x} { y} \) pure fraction in decimals binary set (or integer) \ ((x, y) \ ) number.

ThenobviouslyPlaying table or explore the laws of self-discovery, when the denominator \ (Y \) and \ (\ K) when coprime, \ (\ FRAC {X} {Y} \) pure decimals. And of Fraction molecule must satisfy \ (X \) denominator \ (Y \) prime.

Thus, we get the following persimmon:

\[ans = \sum _ {i = 1} ^ m[\gcd(i, k) = 1] \sum _ {j = 1} ^ n [\gcd(i,j)=1] \]

However, direct enumeration of complexity unacceptable.

Persimmon observed appeared \ ([\ gcd = 1] \) form, which inspired us to use a common modification Mobius inversion:

\[\sum _ {d|x} \mu(x)=[x=1]\]

Which is introduced into the equation, to give:

\[ans= \sum _ {i = 1} ^ {m} \sum _{d|i,d|k} \mu(d) \sum _ {j = 1} ^ {n} \sum _{t|i,t|j} \mu(t)\]

Enumeration consider \ (T \) extracted enumeration \ (J \) in front, the more complex enumerator approximately into simple enumeration multiples . Get (here enumerate \ (j \) is actually \ ( "t \) is \ (j \) times \ (" \) ):

\[\sum_{t|i}^{n}\mu(t)\sum_{j=1}^{\lfloor\frac{n}{t}\rfloor}\]

which is

\[ans= \sum _ {i = 1} ^ {m} \sum _{d|i,d|k} \mu(d)\sum_{t|i}^{n}\mu(t)\lfloor\frac{n}{t}\rfloor\]

Note that here enumerate \ (t \) , we still have \ (t | i \) restrictions. In order to eliminate this restriction , we try to enumerate \ (t \) is transferred to a more forward position, the same enumeration \ (i \) into \ ( "t \) is \ (i \) times \ (" \) :

\[ans=\sum_{t=1}^{\min(n,m)}\mu(t)\lfloor\frac{n}{t}\rfloor\sum_{i=1}^{\lfloor\frac{m}{t}\rfloor}\sum_{d|it,d|k}\mu(d)\]

(Since the enumeration \ (I \) conversion to \ ( "T \) a \ (I \) times \ ( '\) , behind \ (d | i \) becomes \ (D | IT \) )

Solve finished \ (t \) of the problem, enumerate \ (d \) question how should we do?

Guannameduo to do without on the line ww

We found that, if it is determined \ (t \) and \ (d \) value, then the legitimate \ (i \) number that can \ (O (1) \) calculated , and \ (d | k \ ) the conditions are very easy to meet. Then we consider the enumeration \ (d \) referred to earlier, the \ (d | it \) restrictions to \ (i \) to complete :

\[ans=\sum_{d|k}\mu(d)\sum_{t=1}^{\min(n,m)}\mu(t)\lfloor\frac{n}{t}\rfloor\sum_{i,d|it}^{\lfloor\frac{m}{t}\rfloor}\]

Set \ (= W \ GCD (T, D) \) , then:

\[ans=\sum_{d|k}\mu(d)\sum_{t=1}^{\min(n,m)}\mu(t)\lfloor\frac{n}{t}\rfloor\lfloor\frac{mw}{td}\rfloor\]

At this point we've got a relatively good practice violence: Since \ (k \ leq2000 \) , so that \ (\ mu (d) \ not = 0 \) is \ (d \) at most \ (16 \) a linear sieve \ (\ MU \) , violence enumeration \ (D \) and \ (T \) , the time complexity is about \ (O (16 \ min (n-, m)) \) , the desired score \ ( 70 \) around.

Think about why violence is limited to linear time?

Still (d | it \) \ restrictions, so we can not to \ (t \) be divisible block .

Careful observation of violence persimmon, thenTear toastedLook, we find: Due to \ (W = \ GCD (T, D) \) , if it is determined \ (W \) values, \ (I \) limitations on the \ (\ frac {t} { w} \) irrelevant.

Then enumeration \ (\ frac {t} { w} \) is divisible by the block?

\[ans=\sum_{d|k}\mu(d)\sum_{w|d}\mu(w)\sum_{t=1}^{\min(\lfloor\frac{n}{w}\rfloor,\lfloor\frac{m}{d}\rfloor)}[\gcd(t,d)=1]\mu(t)\lfloor\frac{n}{wt}\rfloor\lfloor\frac{m}{td}\rfloor\]

Oh, and so on, that strange \ ([\ gcd (t, d) = 1] \) come from?

The old routine, enumerated here \ (t \) (we call it \ (t '\) it qwq), is actually a \ ( "w \) is \ (t' \) times \ (" \) . And because the original formula \ (= W \ GCD (T, D) \) , so only (\ PERP D \ T ') \ , will not repeat the enumeration.

How to do that? And then split a \ (\ mu \) come out?

[Instinct] this my liberation (physical) .png I do not think so.

Continue to observe the above equation, we found, had \ (\ sum \ mu (t ) \) will need to teach Du screen, it can not be the way to \ (\ gcd \) work together to solve the limitations of it?

Nice try
can.

Thus this invention is a function konjac:

\[ \omega(d,x)=\left\{\begin{aligned}0&,&\gcd(d,x)\not=1\\\mu(x)&,& otherwise\end{aligned}\right.\]

This function into the above equation:

\[ans=\sum_{d|k}\mu(d)\sum_{w|d}\mu(w)\sum_{t=1}^{\min(\lfloor\frac{n}{w}\rfloor,\lfloor\frac{m}{d}\rfloor)}\omega(d, t)\lfloor\frac{n}{wt}\rfloor\lfloor\frac{m}{td}\rfloor\]

Having said all this nonsense, this is not exactly the same, and above persimmon?

However, not. If \ (D \) is a given constant , then the \ (\ omega (d, x ) \) is the product of a. Multiplicative, meaning that you can teach Du screen.

Come, then:

Set \ (g (x) \) is a multiplicative function, requires \ (\ sum_ {i = 1 } ^ xg (x) \) and \ (\ sum_ {i = 1 } ^ x (g * \ omega) ( x) \) can be solved quickly, naturally thought \ (G = the I \) . (Here since the \ (D \) as a constant, \ (\ Omega \) in this parameter is omitted)

Then - we encountered unprecedented challenges (In fact, I dish)

\ (\ sum_ {i = 1 } ^ x (I * \ omega) (x) \) values is how much?

With past experience, I am confident that wrote the

int ret = 1;

Then won \ (64 \) good score points. Du teach all the required screening points spared.

This...

Calm examination, we find that \ (the I * \ Omega \ not = \ Epsilon \) .

For \ (I * \ mu \) , any \ (X \) as long as the quality factor has at least one, can be proved by the binomial theorem \ ((the I * \ MU) (X) = 0 \) .

But \ (I * \ omega \) it? Since the introduction of (\ gcd (d, x) \) \ restriction, only when \ (X \) have at least one and \ (D \) prime prime factors when we can get \ ((I * \ omega ) (X) = 0 \) . So we ask each sieve Du teach \ (\ omega (d, x ) \) when the need to use a \ (DFS \) is satisfied \ (1 \ leq i \ leq x, \ gcd (i, d) = 1 \) the \ (i \) number, in order to properly teach Du screen.

Then enumeration \ (D \) , \ (W \) , for \ (T \) divisible block, Du teach screen \ (\ Omega (D, T) \) , it may be \ (O (3 ^ { h (k)} \ sqrt [ \ frac {2} {3}] {\ min (n, m)}) \) bound (in time complexity \ (h (k) \) means \ (K \) the number of quality factors, and the actual running far less than this upper bound) are complete.

Well,Excluding one hour wrong variable name debuggingThis question is to solve it smoothly ~ ☆

Attach Code:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define R register
#define ll long long
using namespace std;
const int N = 1e6;

int n, m, k, omg[16][N + 10], ispr[N + 10], prime[N], nopr, num, p[5], somg[16][N + 10], miu[20], d[20];
unordered_map<int, int>sum[16];

inline void pre() {
    int tp = k;
    for (R int i = 2; i * i <= k; ++i) {
        if (tp % i == 0) {
            p[++num] = i;
            while (tp % i == 0)
                tp /= i;
        }
    }
    if (tp != 1)
        p[++num] = tp;
    for (R int i = 0; i < (1 << num); ++i) {
        d[i] = 1, miu[i] = 1;
        for (R int j = 0; j < num; ++j)
            if (i & (1 << j))
                d[i] *= p[j + 1], miu[i] *= -1;
    }
    for (R int i = 0; i < (1 << num); ++i)
        somg[i][1] = 1;
    for (R int i = 2; i <= N; ++i) {
        if (!ispr[i]) {
            for (R int j = 0; j < (1 << num); ++j)
                if (d[j] % i)
                    omg[j][i] = -1;
            prime[++nopr] = i;
        }
        for (R int j = 0; j < (1 << num); ++j)
            somg[j][i] = somg[j][i - 1] + omg[j][i];
        for (R int j = 1, t; j <= nopr && (t = prime[j] * i) <= N; ++j) {
            ispr[t] = 1;
            if (i % prime[j] == 0) {
                for (R int u = 0; u < (1 << num); ++u)
                    omg[u][t] = 0;
                break;
            }
            for (R int u = 0; u < (1 << num); ++u)
                omg[u][t] = omg[u][i] * (d[u] % prime[j] ? -1 : 0);
        }
    }
    return;
}

int dfs(int u, int step, int mul, int lim) {
    if (step == num)
        return 1;
    if (~u & (1 << step))
        return dfs(u, step + 1, mul, lim);
    int ret = 0;
    for (R ll i = 1, j; (j = i * mul) <= lim; i *= p[step + 1])
        ret += dfs(u, step + 1, j, lim);
    return ret;
}

int calc(int u, int x) {
    if (x <= N)
        return somg[u][x];
    if (sum[u].find(x) != sum[u].end())
        return sum[u][x];
    int ret = dfs(u, 0, 1, x), i;
    for (i = 2; i * i <= x; ++i)
        ret -= calc(u, x / i);
    for (R int k = x / i, j; i <= x; i = j + 1, --k)
        j = x / k, ret -= (j - i + 1) * calc(u, k);
    return sum[u][x] = ret;
}

int main() {
    cin >> n >> m >> k;
    pre();
    ll ans = 0;
    for (R int i = 0; i < (1 << num); ++i) {
        for (R int j = 0; j < (1 << num); ++j) {
            if (d[i] % d[j])
                continue;
            ll nx = n / d[j], mx = m / d[i];
            if (nx > mx)
                swap(nx, mx);
            for (R int u = 1, v; u <= nx; u = v + 1) {
                v = min(nx / (nx / u), mx / (mx / u));
                ans += miu[i] * miu[j] * (calc(i, v) - calc(i, u - 1)) * (nx / u) * (mx / u);
            }
        }
    }
    cout << ans;
    return 0;//呐,想着复制代码的大哥哥,恋恋就在你身后哟
}

Guess you like

Origin www.cnblogs.com/suwakow/p/11375057.html
Recommended