Pagini recente » Cod sursa (job #2769384) | Cod sursa (job #2381765) | Cod sursa (job #1864287) | Cod sursa (job #2855420) | Cod sursa (job #1500002)
#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(primes[idx - 1] >= getBackPrime(step))
idx--;
}
for(auto temp : ans)
cout << temp << " ";
cout << "\n";
}