[cf 1208G] Polygons

The meaning of problems

Drawn in the circumferential \ (K \) within a regular polygon, requires \ (K \) a different number of sides of a regular polygon, and the maximum number of edges does not exceed \ (n-\) , so as to minimize the total number of vertices.

answer

Immortal title reflects the fact that I will not mathematics.
If you choose to consider a positive \ (n \) gon, then there must be selected to meet the \ (m | n \) n \ (m \) gon.
Taking into account the optimal solution, we will let all polygons a common point.
Consider this point \ (O \) , the circumferential length is set 1, then n \ (n-\) point on the polygonal \ (O \) circle distance as
{n} \ [\ frac { 0} , \ frac {1} {n
}, \ frac {2} {n}, \ ldots, \ frac {n - 1} {n} \] considered as selected from the n \ (n-\) gon time, will satisfying a \ (m | n \) n \ (m \) polygon.
This corresponds to n \ (n-\) gon own contribution is generated denominator \ (n-\) number of proper fractions the simplest (removal \ (\ {n-FRAC {0}} \) ).
Thus, in order to select \ (k \) a regular polygon, we should let alone elected regular polygon and the minimum contribution generated.
Such a sequence just before discharge to take \ (K \)Small sums can be.
Note that, because there is no "one side shaped" and "two-sided", but they are still in line with our above analogy analysis.
So it can make "side shape" contribution to 1 (representing \ (O \) , i.e., \ (\ FRAC {0} {n-} \) ), "two-sided" contribution to 1 (i.e., \ (\ FRAC {1} {2} \) ).
In the (k> 1 \) \ , they include contributions to come (in the \ (k = 1 \) , the "two-sided" no contribution), but the absence of "side-shaped", "two-sided "this kind of thing can not be counted \ (k \) a regular polygon inside.

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 5;
int n, k; long long ans;
int p[N], phi[N]; bool vis[N];
vector <int> coe;
void sieve () {
    for (int i = 2; i <= n; ++i) {
        if (!vis[i]) {
            p[++p[0]] = i;
            phi[i] = i - 1;
        }
        for (int j = 1; j <= p[0] && i * p[j] <= n; ++j) {
            vis[i * p[j]] = 1;
            if (i % p[j] == 0) {
                phi[i * p[j]] = phi[i] * p[j];
                break;
            }
            phi[i * p[j]] = phi[i] * (p[j] - 1);
        }
    }
}

int main () {
    cin >> n >> k, sieve();
    if (k == 1) {
        return puts("3"), 0;
    }
    for (int i = 3; i <= n; ++i) {
        coe.push_back(phi[i]);
    }
    sort(coe.begin(), coe.end());
    for (int i = 0; i < k; ++i) {
        ans += coe[i];
    }
    cout << ans + 2 << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/psimonw/p/11615363.html