#include #include #include #include #include #include using namespace std; // Structure for incremental cost calculation struct SceneSchedule { vector schedule; vector first_appearance; vector last_appearance; long long total_cost; SceneSchedule(int N, int M) : schedule(M), first_appearance(N + 1, -1), last_appearance(N + 1, -1), total_cost(0) {} }; // Calculate cost change for a potential swap long long calculateSwapDelta(const vector>& actors_in_scenes, const vector& actor_costs, SceneSchedule& curr_schedule, int pos1, int pos2) { long long delta = 0; unordered_set affected_actors; // Collect affected actors from both positions for (int actor : actors_in_scenes[curr_schedule.schedule[pos1] - 1]) affected_actors.insert(actor); for (int actor : actors_in_scenes[curr_schedule.schedule[pos2] - 1]) affected_actors.insert(actor); // Calculate old cost for affected actors for (int actor : affected_actors) { if (curr_schedule.first_appearance[actor] != -1) { int old_duration = curr_schedule.last_appearance[actor] - curr_schedule.first_appearance[actor] + 1; delta -= (long long)old_duration * actor_costs[actor - 1]; } } // Temporarily swap scenes swap(curr_schedule.schedule[pos1], curr_schedule.schedule[pos2]); // Recalculate appearances for affected actors for (int actor : affected_actors) { curr_schedule.first_appearance[actor] = -1; curr_schedule.last_appearance[actor] = -1; } // Update appearances and calculate new cost for (int pos = 0; pos < curr_schedule.schedule.size(); pos++) { int scene = curr_schedule.schedule[pos]; for (int actor : actors_in_scenes[scene - 1]) { if (affected_actors.count(actor)) { if (curr_schedule.first_appearance[actor] == -1) { curr_schedule.first_appearance[actor] = pos; } curr_schedule.last_appearance[actor] = pos; } } } // Calculate new cost for affected actors for (int actor : affected_actors) { if (curr_schedule.first_appearance[actor] != -1) { int new_duration = curr_schedule.last_appearance[actor] - curr_schedule.first_appearance[actor] + 1; delta += (long long)new_duration * actor_costs[actor - 1]; } } // Restore original schedule swap(curr_schedule.schedule[pos1], curr_schedule.schedule[pos2]); // Restore original appearances for (int actor : affected_actors) { curr_schedule.first_appearance[actor] = -1; curr_schedule.last_appearance[actor] = -1; } for (int pos = 0; pos < curr_schedule.schedule.size(); pos++) { int scene = curr_schedule.schedule[pos]; for (int actor : actors_in_scenes[scene - 1]) { if (affected_actors.count(actor)) { if (curr_schedule.first_appearance[actor] == -1) { curr_schedule.first_appearance[actor] = pos; } curr_schedule.last_appearance[actor] = pos; } } } return delta; } // Initialize schedule state void initializeScheduleState(SceneSchedule& state, const vector>& actors_in_scenes) { for (int pos = 0; pos < state.schedule.size(); pos++) { int scene = state.schedule[pos]; for (int actor : actors_in_scenes[scene - 1]) { if (state.first_appearance[actor] == -1) { state.first_appearance[actor] = pos; } state.last_appearance[actor] = pos; } } } vector optimizeSceneSchedule(int N, int M, const vector& actor_costs, const vector>& scenes_info) { vector> actors_in_scenes = scenes_info; vector> actor_metrics; // (scene_count, actor) // Count scenes per actor vector scene_count(N + 1, 0); for (const auto& scene : scenes_info) { for (int actor : scene) { scene_count[actor]++; } } // Create actor metrics for (int actor = 1; actor <= N; actor++) { if (scene_count[actor] > 0) { actor_metrics.push_back({scene_count[actor], actor}); } } // Sort by scene count (ascending) and cost (descending) sort(actor_metrics.begin(), actor_metrics.end(), [&](const auto& a, const auto& b) { if (a.first != b.first) return a.first < b.first; return actor_costs[a.second - 1] > actor_costs[b.second - 1]; }); // Initialize schedule SceneSchedule curr_schedule(N, M); vector used(M + 1, false); int schedule_pos = 0; // Build initial schedule for (const auto& [count, actor] : actor_metrics) { for (int scene = 1; scene <= M; scene++) { if (!used[scene] && find(scenes_info[scene-1].begin(), scenes_info[scene-1].end(), actor) != scenes_info[scene-1].end()) { curr_schedule.schedule[schedule_pos++] = scene; used[scene] = true; } } } // Add remaining scenes for (int scene = 1; scene <= M; scene++) { if (!used[scene]) { curr_schedule.schedule[schedule_pos++] = scene; } } // Initialize state initializeScheduleState(curr_schedule, actors_in_scenes); // Limited local optimization const int MAX_ITERATIONS = 100; const int WINDOW_SIZE = 10; for (int iter = 0; iter < MAX_ITERATIONS; iter++) { bool improved = false; // Try swaps within sliding windows for (int start = 0; start < M - WINDOW_SIZE && !improved; start += WINDOW_SIZE/2) { int end = min(start + WINDOW_SIZE, M); for (int i = start; i < end && !improved; i++) { for (int j = i + 1; j < end && !improved; j++) { long long delta = calculateSwapDelta(actors_in_scenes, actor_costs, curr_schedule, i, j); if (delta < 0) { swap(curr_schedule.schedule[i], curr_schedule.schedule[j]); improved = true; initializeScheduleState(curr_schedule, actors_in_scenes); } } } } if (!improved) break; } return curr_schedule.schedule; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); freopen("star.in", "r", stdin); freopen("star.out", "w", stdout); int N, M; cin >> N >> M; vector actor_costs(N); for (int i = 0; i < N; i++) { cin >> actor_costs[i]; } vector> scenes_info(M); for (int i = 0; i < M; i++) { int br; cin >> br; scenes_info[i].resize(br); for (int j = 0; j < br; j++) { cin >> scenes_info[i][j]; } } vector result = optimizeSceneSchedule(N, M, actor_costs, scenes_info); for (int i = 0; i < M; i++) { cout << result[i] << (i < M - 1 ? " " : "\n"); } return 0; }