結果
| 問題 |
No.1270 Range Arrange Query
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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;
}
qwewe