Cod sursa(job #1500006)

Utilizator klamathixMihai Calancea klamathix Data 11 octombrie 2015 13:54:20
Problema NumMst Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-7;

int main() {
    #ifdef INFOARENA
    ifstream cin("nummst.in");
    ofstream cout("nummst.out");
    #endif

    int n; cin >> n;
    
    int g = 0;

    for(int d = 2; d <= n; ++d)
        if(n % d == 0) {
            g = n / d;
            break;
        }
    
    n /= g;
    vector<int> primes;
    
    auto isPrime = [] (int a) {
        for(int i = 2; i * i <= a; ++i)
            if(a % i == 0)
                return false;
        return true;
    };
    
    for(int i = 2; i <= n; ++i)
        if(isPrime(i))
            primes.push_back(i);
    
    int pCount = primes.size();
     
    vector<vector<int>> from(pCount + 1, vector<int> (n + 1, 0));
    vector<double> best(n + 1, 0);

    for(int i = 1; i <= n; ++i)
        from[0][i] = i - 1;

    for(int i = 0; i < pCount; ++i) {
        vector<double> tempBest(n + 1, 0.0);
        vector<int> tempFrom(n + 1, 0);
        
        int current = primes[i];
        while(current <= n) {
            double logC = log(current);
            vector<double> nowBest(n + 1, 0.0);
            vector<int> nowFrom(n + 1, 0);
            
            if(current == n)
                break;

            for(int j = n - current; j >= 0; --j)
                if(best[j] + logC >= nowBest[j + current]) {
                    nowBest[j + current] = best[j] + logC;
                    nowFrom[j + current] = j;
                }
            
            for(int j = 0; j <= n; ++j)
                if(nowBest[j] >= tempBest[j] && nowBest[j]) {
                    tempBest[j] = nowBest[j];
                    tempFrom[j] = nowFrom[j];
                }
            
            current *= primes[i];
        }

        for(int j = 0; j <= n; ++j)
            if(tempBest[j] && best[j] <= tempBest[j]) {
                best[j] = tempBest[j];
                from[i + 1][j] = tempFrom[j];
            } else {
                from[i + 1][j] = from[i][j];
            }
    }

    int idx = pCount;
    vector<int> ans;
    
    auto getBackPrime = [&](int x) {
        if(x == 1)
            return 1;
        for(int i = 0; i < pCount; ++i)
            if(x % primes[i] == 0)
                return primes[i];
        return -1;
    };
    
    for(int tmp = n; tmp;) {
        //cerr << tmp << " " << idx << " " << from[idx][tmp] << "\n";
        
        int step = tmp - from[idx][tmp];
        ans.push_back(g * (tmp - from[idx][tmp]));
        tmp = from[idx][tmp];
        
        if(step == 1)
            continue;

        while(idx > 0 && primes[idx - 1] >= getBackPrime(step))
            idx--;
    }

    for(auto temp : ans)
        cout << temp << " ";
    cout << "\n";
}