// Sort reductions in descending order sort(reductions.begin(), reductions.end(), [](const ReductionInfo& r1, const ReductionInfo& r2) { // Sort by reduction descending. If reductions are equal, order doesn't matter much, // but consistent sorting is good (e.g., by index ascending). if (r2.reduction != r1.reduction) { return r2.reduction < r1.reduction; // Descending reduction } return r1.originalIndex < r2.originalIndex; // Ascending index as tie-breaker });
// Identify indices to remove unordered_set<int> removedIndices; for (int i = 0; i < k; i++) { removedIndices.insert(reductions[i].originalIndex); }
// Build the new list of songs (kept songs) vector<int> keptSongs; for (int i = 0; i < n; i++) { if (removedIndices.find(i + 1) == removedIndices.end()) { // Check using 1-based index keptSongs.push_back(a[i]); } }
// Calculate the total waiting time for the kept songs longlong finalTotalWait = 0; longlong currentPrefixSumNew = 0; for (int songLength : keptSongs) { finalTotalWait += currentPrefixSumNew; currentPrefixSumNew += songLength; }
vector<vector<int>> adj; vector<char> colors; // 0-based node index vector<int> weights; // 0-based node index vector<longlong> subtreeSum; // S[u]: sum of weights in subtree rooted at u vector<vector<longlong>> dpDown; // dpDown[u][color_idx]: cost for subtree u if parent imposes target color vector<vector<longlong>> finalCost; // finalCost[u][color_idx]: total cost if u is root and target color is color_idx longlong totalWeightSum; constint R_IDX = 0; constint G_IDX = 1; constint B_IDX = 2; int n;
// Helper to map color char to index 0, 1, 2 intcolorToIndex(char c){ if (c == 'R') return R_IDX; if (c == 'G') return G_IDX; return B_IDX; // 'B' }
// DFS1: Calculate subtree sums, starting from node 0 voiddfs_sum(int u, int p){ subtreeSum[u] = weights[u]; for (int v : adj[u]) { if (v != p) { dfs_sum(v, u); subtreeSum[u] += subtreeSum[v]; } } }
voiddfs_dp_down(int u, int p){ for (int v : adj[u]) { if (v != p) { dfs_dp_down(v, u); // Calculate for child first int vColorIdx = colorToIndex(colors[v]); longlong sv = subtreeSum[v]; // Subtree sum of child v
for (int targetColorIdx = 0; targetColorIdx < 3; targetColorIdx++) { if (vColorIdx == targetColorIdx) { // If child color matches target, add child's dpDown cost for that target dpDown[u][targetColorIdx] += dpDown[v][targetColorIdx]; } else { // If child color differs, must modify child's subtree, cost is S[v] dpDown[u][targetColorIdx] += sv; } } } } }
// Helper to get contribution of child x's subtree when target is C, from parent's view longlonggetContribution(int x, int targetColorIdx){ int xColorIdx = colorToIndex(colors[x]); if (xColorIdx == targetColorIdx) { // If x matches target, contribution is the cost calculated below x for that target return dpDown[x][targetColorIdx]; } else { // If x doesn't match target, the whole subtree x must be modified, cost is S[x] return subtreeSum[x]; } }
// DFS3: Rerooting to calculate finalCost[u][C] = cost if u is root and target is C voiddfs_reroot(int u, int p){ for (int v : adj[u]) { if (v != p) { // Calculate cost contribution from the 'parent' branch (everything except v's subtree) for (int targetColorIdx = 0; targetColorIdx < 3; targetColorIdx++) { longlong costParentBranch; // Cost of the tree excluding v's subtree, assuming targetColorIdx
longlong contributionFromV = getContribution(v, targetColorIdx); // Weight sum of the parent branch (everything except v's subtree) longlong sumExcludingVSubtree = totalWeightSum - subtreeSum[v];
int uColorIdx = colorToIndex(colors[u]); if (uColorIdx == targetColorIdx) { // If u matches target, the cost from parent branch is its calculated cost, // which is the total cost from u's perspective minus v's contribution. costParentBranch = finalCost[u][targetColorIdx] - contributionFromV; } else { // If u doesn't match target, from v's perspective, u must be modified. // The cost incurred by this modification is the sum of weights in that branch. costParentBranch = sumExcludingVSubtree; } // Total cost for v = (cost below v) + (cost from parent branch) finalCost[v][targetColorIdx] = dpDown[v][targetColorIdx] + costParentBranch; } // Recurse into child v dfs_reroot(v, u); } } }
// Step 2: Calculate dpDown (cost from below, relative to root 0) dfs_dp_down(0, -1);
// Step 3: Rerooting DP // Initialize root's finalCost (cost if 0 is root = cost below 0) for (int c = 0; c < 3; ++c) { finalCost[0][c] = dpDown[0][c]; } // Start rerooting DFS from root 0 to calculate finalCost for all nodes dfs_reroot(0, -1);
// Step 4: Find minimum cost longlong minTotalCost = LLONG_MAX; for (int r = 0; r < n; ++r) { int targetColorIdx = colorToIndex(colors[r]); // Target color is initial color of root r minTotalCost = min(minTotalCost, finalCost[r][targetColorIdx]); }