結果
問題 |
No.1270 Range Arrange Query
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:20:27 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,091 bytes |
コンパイル時間 | 1,116 ms |
コンパイル使用メモリ | 82,704 KB |
実行使用メモリ | 6,272 KB |
最終ジャッジ日時 | 2025-05-14 13:22:18 |
合計ジャッジ時間 | 10,069 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 3 TLE * 1 -- * 11 |
ソースコード
#include <iostream> #include <vector> #include <algorithm> const long long INF = 4e18; // Sufficiently large infinity (max N*N inversions or N*M costs) // Fenwick tree (BIT) struct FenwickTree { std::vector<int> bit; int size; FenwickTree(int n) : size(n), bit(n + 1, 0) {} void update(int idx, int delta) { // 1-indexed for (; idx <= size; idx += idx & -idx) { bit[idx] += delta; } } int query(int idx) { // 1-indexed, prefix sum up to idx int sum = 0; for (; idx > 0; idx -= idx & -idx) { sum += bit[idx]; } return sum; } // Query sum in [val_l, val_r] int query_val_range(int val_l, int val_r) { if (val_l > val_r) return 0; return query(val_r) - query(val_l - 1); } void reset() { // Reset BIT to all zeros std::fill(bit.begin(), bit.end(), 0); } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N_val, Q_val; // Using _val to avoid conflict with N in problem description std::cin >> N_val >> Q_val; std::vector<int> A(N_val); for (int i = 0; i < N_val; ++i) { std::cin >> A[i]; } FenwickTree ft(N_val); // Max value is N_val std::vector<int> cost_val_arr(N_val + 1); std::vector<long long> dp_prev(N_val + 1); std::vector<long long> dp_curr(N_val + 1); std::vector<long long> min_so_far(N_val + 1); std::vector<int> freq_L(N_val + 1, 0); std::vector<int> freq_R(N_val + 1, 0); for (int q_idx = 0; q_idx < Q_val; ++q_idx) { int l_query, r_query; std::cin >> l_query >> r_query; // Adjust to 0-indexed int l_idx = l_query - 1; int r_idx = r_query - 1; long long fixed_inversions = 0; // 1. Inversions in A[0...l_idx-1] ft.reset(); for (int i = 0; i < l_idx; ++i) { fixed_inversions += ft.query_val_range(A[i] + 1, N_val); ft.update(A[i], 1); } // 2. Inversions in A[r_idx+1...N_val-1] ft.reset(); for (int i = r_idx + 1; i < N_val; ++i) { fixed_inversions += ft.query_val_range(A[i] + 1, N_val); ft.update(A[i], 1); } // 3. Inversions (A[i], A[j]) where i < l_idx and j > r_idx ft.reset(); for (int i = r_idx + 1; i < N_val; ++i) { ft.update(A[i], 1); } for (int i = 0; i < l_idx; ++i) { if (A[i] > 1) { fixed_inversions += ft.query(A[i] - 1); } } // Calculate Cost(v) for v = 1...N_val // Cost(v) = (count i < l_idx: A[i] > v) + (count j > r_idx: v > A[j]) // Optimize freq_L/R fill if N_val is large vs l_idx / (N_val-1-r_idx) // current fill is ok as they are cleared first std::fill(freq_L.begin(), freq_L.end(), 0); std::fill(freq_R.begin(), freq_R.end(), 0); for (int i = 0; i < l_idx; ++i) { freq_L[A[i]]++; } for (int i = r_idx + 1; i < N_val; ++i) { freq_R[A[i]]++; } // Calculate first part of Cost(v): (count i < l_idx: A[i] > v) // cost_val_arr[v] = sum_{x=v+1 to N_val} freq_L[x] cost_val_arr[N_val] = 0; int current_sum_L = 0; for(int v = N_val - 1; v >= 1; --v) { current_sum_L += freq_L[v+1]; cost_val_arr[v] = current_sum_L; } // Add second part of Cost(v): (count j > r_idx: v > A[j]) // sum_{x=1 to v-1} freq_R[x] int current_sum_R = 0; // For v=1, sum_{x=1 to 0} is 0. cost_val_arr[1] correctly gets current_sum_R=0 added. for (int v = 1; v <= N_val; ++v) { if (v > 1) current_sum_R += freq_R[v-1]; cost_val_arr[v] += current_sum_R; } int M = r_idx - l_idx + 1; // M is always >= 1 because 1 <= l_query <= r_query <= N_val // DP part for (int val = 1; val <= N_val; ++val) { dp_prev[val] = cost_val_arr[val]; } for (int k = 2; k <= M; ++k) { min_so_far[1] = dp_prev[1]; for (int val = 2; val <= N_val; ++val) { min_so_far[val] = std::min(min_so_far[val-1], dp_prev[val]); } for (int val = 1; val <= N_val; ++val) { if (min_so_far[val] >= INF) { dp_curr[val] = INF; } else { dp_curr[val] = cost_val_arr[val] + min_so_far[val]; } } // Use std::swap or copy, std::vector assignment is a copy dp_prev = dp_curr; } long long min_sum_cost_for_range = INF; for (int val = 1; val <= N_val; ++val) { min_sum_cost_for_range = std::min(min_sum_cost_for_range, dp_prev[val]); } if (M==0) min_sum_cost_for_range = 0; // Should not happen with M >= 1 std::cout << fixed_inversions + min_sum_cost_for_range << "\n"; } return 0; }