give solution in cpp #include <bits/stdc++.h> usi...
Создано: 23 июня 2025 г.
Отвечено с использованием O4 Mini High от Chat01
Создано: 23 июня 2025 г.
Отвечено с использованием O4 Mini High от Chat01
give solution in cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int M = 500000;
const int INF = 1000000000;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
text// 1) Precompute divisors for all n<=M static vector<int> divs[M+1]; for(int d = 1; d <= M; d += 2){ // only odd divisors matter, but we can do all for(int x = d; x <= M; x += d){ divs[x].push_back(d); } } // 2) dpNodes[f] = min size of a subtree (excluding the global root) // whose A-value = f. We only care about odd f. static int dpNodes[M+1], D[M+1]; // D[g] = minimal sum of dpNodes[fi] over a factorization g = ∏ fi (all fi odd>1) // (i.e. best way to break g into children at an *internal* node) memset(dpNodes, 0x3f, sizeof dpNodes); memset(D, 0x3f, sizeof D); dpNodes[1] = 0; // no nodes needed to realize A=1 (empty product) D[1] = 0; // to factor 1 you pick nothing // Build up dpNodes in increasing order of f=3,5,7,...,M for(int f = 3; f <= M; f += 2){ int g = f - 2; // g = product of child A-values // compute D[g] = min_{d|g, d>1} ( dpNodes[d] + D[g/d] ) if(g > 1){ int best = INF; for(int d: divs[g]){ if(d == 1) continue; best = min(best, dpNodes[d] + D[g/d]); } D[g] = best; } // start with the “path”‐shape cost dpNodes[f] = (f - 1) / 2; // or use an internal node giving A = g+2 // cost = 1 (the internal node) + D[g] dpNodes[f] = min(dpNodes[f], 1 + D[g]); } // 3) dpRoot[m] = min #vertices in a full tree with exactly m colorings // Root must be green ⇒ m = ∏ A[v_i]. We pay 1 for the root plus // dpNodes[A[v_i]] for each child‐subtree. static int dpRoot[M+1]; for(int i = 0; i <= M; i++) dpRoot[i] = INF; dpRoot[1] = 1; // only the root, 1 beautiful coloring // fill in for odd m ≥3: for(int m = 3; m <= M; m += 2){ // one‐child decomposition: root→subtree with A=m if(dpNodes[m] < INF) dpRoot[m] = 1 + dpNodes[m]; // try splitting m = f * (m/f) for(int f: divs[m]){ if(f == 1 || f == m) continue; dpRoot[m] = min(dpRoot[m], dpRoot[m/f] + dpNodes[f]); } } // 4) answer queries int T; cin >> T; while(T--){ int m; cin >> m; if(m == 1){ cout << 1 << "\n"; } else if((m & 1) == 0){ cout << -1 << "\n"; } else { int ans = dpRoot[m]; if(ans >= INF) ans = -1; cout << ans << "\n"; } } return 0;
}
cpp#include <bits/stdc++.h> using namespace std; using ll = long long; const int M = 500000; const int INF = 1000000000; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); // 1) Precompute odd divisors for all n <= M static vector<int> divs[M+1]; for(int d = 1; d <= M; d += 2) { for(int x = d; x <= M; x += d) { divs[x].push_back(d); } } // 2) dpNodes[f] = minimum size of a subtree (excluding the global root) // whose A-value = f. Only odd f. // D[g] = minimal sum of dpNodes[d_i] over any factorization g = ∏ d_i (all d_i odd > 1) static int dpNodes[M+1], D[M+1]; fill(dpNodes, dpNodes+M+1, INF); fill(D, D+M+1, INF); dpNodes[1] = 0; // no nodes needed for A=1 D[1] = 0; // empty product for g=1 // Build dpNodes in increasing odd f for(int f = 3; f <= M; f += 2) { int g = f - 2; // product of child A-values // Compute D[g]: best way to factor g into odd >1 pieces if (g > 1) { int best = INF; for(int d : divs[g]) { if (d == 1) continue; best = min(best, dpNodes[d] + D[g/d]); } D[g] = best; } // Option 1: path shape cost = (f-1)/2 dpNodes[f] = (f - 1) / 2; // Option 2: use an internal node of A=f => cost = 1 + D[g] dpNodes[f] = min(dpNodes[f], 1 + D[g]); } // 3) dpRoot[m] = minimum total vertices in a full tree with exactly m colorings, // where root is green (so m = ∏ A[child]). static int dpRoot[M+1]; fill(dpRoot, dpRoot+M+1, INF); dpRoot[1] = 1; // only the root for(int m = 3; m <= M; m += 2) { // Single-child: root -> subtree with A = m if (dpNodes[m] < INF) { dpRoot[m] = 1 + dpNodes[m]; } // Multi-child splits: m = f * (m/f) for(int f : divs[m]) { if (f == 1 || f == m) continue; dpRoot[m] = min(dpRoot[m], dpRoot[m/f] + dpNodes[f]); } } // 4) Answer queries int T; cin >> T; while (T--) { int m; cin >> m; if (m == 1) { cout << 1 << "\n"; } else if ((m & 1) == 0) { cout << -1 << "\n"; } else { int ans = dpRoot[m]; cout << (ans >= INF ? -1 : ans) << "\n"; } } return 0; }
Explanation of Key Steps
dpNodes[f]
Calculation
dpRoot[m]
Calculation