Cod sursa(job #994787)

Utilizator primulDarie Sergiu primul Data 6 septembrie 2013 12:52:35
Problema NumMst Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
 
#include <vector>
#include <algorithm>
 
using namespace std;
 
const int MAX_PRIMES = 500;
const int MAX_SQRT = 3500;
 
int N, GCD, Primes[MAX_PRIMES], Father[MAX_PRIMES][MAX_SQRT];
double DP[2][MAX_SQRT];
 
void FindGCD() {
    GCD = -1;
    for (int d = 2; d * d <= N && GCD == -1; ++d)
        if (N % d == 0)
            GCD = N / d;
}
 
void Eratosthenes() {
    vector<bool> isComposite = vector<bool>(MAX_SQRT, false);
    for (int i = 2; i < MAX_SQRT; ++i) {
        if (isComposite[i])
            continue;
        Primes[++Primes[0]] = i;
        for (int j = i * i; j < MAX_SQRT; j += i)
            isComposite[j] = true;
    }
}
 
void SolveDP() {
    N /= GCD;
    for (int i = 1; i <= N; ++i)
        DP[0][i] = log(1.0);
    for (int k = 1; Primes[k] < N; ++k) {
        for (int n = 1; n <= N; ++n) {
            DP[1][n] = DP[0][n];
            Father[k][n] = 0;
            for (int value = Primes[k]; value <= n; value *= Primes[k]) {
                if (DP[1][n] < DP[0][n - value] + log(1.0 * value)) {
                    DP[1][n] = DP[0][n - value] + log(1.0 * value);
                    Father[k][n] = value;
                }
            }
        }
        memcpy(DP[0], DP[1], sizeof(DP[1]));
    }
}
 
void Solve() {
    Eratosthenes();
    FindGCD();
    SolveDP();
}
 
void Read() {
    assert(freopen("nummst.in", "r", stdin));
    assert(scanf("%d", &N) == 1);
}
 
void Print() {
    assert(freopen("nummst.out", "w", stdout));
    int n = N, k = 1;
    for (; Primes[k + 1] < N; ++k);
    for (; k > 0; --k) {
        if (Father[k][n] != 0)
            printf("%d ", GCD * Father[k][n]);
        n -= Father[k][n];
    }
    for (; n > 0; --n)
        printf("%d ", GCD);
    printf("\n");
}
 
int main() {
    Read();
    Solve();
    Print();
    return 0;
}