結果
| 問題 |
No.2036 Max Middle
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:16:29 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 6,696 bytes |
| コンパイル時間 | 1,005 ms |
| コンパイル使用メモリ | 91,008 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2025-05-14 13:17:50 |
| 合計ジャッジ時間 | 5,393 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 4 TLE * 1 -- * 12 |
ソースコード
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;
// Use long long for array values because the operation can decrease values potentially below the standard int range.
typedef long long ll;
// Global vector A to store the sequence, and N for its size.
vector<ll> A;
int N;
// A set to keep track of the indices k where A[k] is currently a peak.
// Using a set allows efficient checking of existence, insertion, and deletion (O(log N)).
set<int> peak_indices;
// A queue to manage the indices of peaks that need to be processed.
// Using a queue implements a breadth-first like processing order of peaks.
queue<int> worklist;
// Function to check if the element A[k] is a peak.
// According to the problem, A[k] is a peak if k is between 1 and N-2 (inclusive, using 0-based indexing for A)
// and satisfies the condition A[k-1] < A[k] and A[k] > A[k+1].
// Note: The problem statement uses 1-based indexing and defines the operation for index `i` where 1 <= i <= N-2.
// This corresponds to checking the triplet (A_i, A_{i+1}, A_{i+2}). In 0-based indexing, this triplet is (A[i-1], A[i], A[i+1]).
// The peak condition is A[i-1] < A[i] and A[i] > A[i+1].
// The element modified is A[i]. Let's denote the index `i` (from problem statement) as `k` in our code.
// So `k` represents the index of the element being modified/checked if it's a peak. Valid range for k is [1, N-2].
bool is_peak(int k) {
// Check if index k is within the valid range for a peak [1, N-2].
if (k < 1 || k > N - 2) {
return false;
}
// Check the peak condition: the element A[k] must be strictly greater than its left neighbor A[k-1]
// and strictly greater than its right neighbor A[k+1].
return A[k-1] < A[k] && A[k] > A[k+1];
}
// Function to update the status of a potential peak at index k.
// If k becomes a peak and wasn't tracked, add it to the set and worklist.
// If k ceases to be a peak and was tracked, remove it from the set.
void update_peak_status(int k) {
// Check if index k is within the valid range [1, N-2]. Indices outside this range cannot be peaks.
if (k < 1 || k > N - 2) {
return;
}
// Determine if A[k] is currently a peak based on current values of A.
bool current_is_peak = is_peak(k);
// Check if index k is currently present in our set of peak indices.
bool is_in_set = peak_indices.count(k);
// Case 1: A[k] is currently a peak, but k is not in our set.
// This means k has just become a peak (or was missed initially).
if (current_is_peak && !is_in_set) {
peak_indices.insert(k); // Add k to the set of peak indices.
worklist.push(k); // Add k to the worklist queue to be processed later.
}
// Case 2: A[k] is not currently a peak, but k is in our set.
// This means k used to be a peak but isn't anymore due to changes in neighbors.
else if (!current_is_peak && is_in_set) {
peak_indices.erase(k); // Remove k from the set of peak indices.
// Note: k might still be present in the worklist queue. If it gets popped later,
// the check `if (peak_indices.count(k) == 0)` will correctly skip it.
}
// Other cases:
// - If current_is_peak is true and is_in_set is true, k is already a known peak. No action needed.
// - If current_is_peak is false and is_in_set is false, k is not a peak and not tracked. No action needed.
}
int main() {
// Use faster I/O operations
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Read the size of the sequence N.
cin >> N;
// Resize the vector A to hold N elements.
A.resize(N);
// Read the N integer elements into vector A.
for (int i = 0; i < N; ++i) {
cin >> A[i];
}
// Initialize the process by finding all initial peaks.
// Iterate through all possible indices k that can be a peak (1 to N-2).
for (int k = 1; k <= N - 2; ++k) {
if (is_peak(k)) { // If A[k] satisfies the peak condition
peak_indices.insert(k); // Add its index k to the set of peaks.
worklist.push(k); // Add its index k to the initial worklist queue.
}
}
// Variable to keep track of the total number of operations performed.
ll total_ops = 0;
// Main loop: Process peaks from the worklist as long as it's not empty.
while (!worklist.empty()) {
int k = worklist.front(); // Get the index of the peak element A[k] from the front of the queue.
worklist.pop(); // Remove this index from the queue.
// Check if the index k is still present in the set of active peaks.
// It might have been removed if it ceased to be a peak due to a previous operation on a neighbor.
// If it's not in the set, skip processing it.
if (peak_indices.count(k) == 0) {
continue;
}
// If k is in the set, it's a valid peak to operate on.
// Remove k from the set because we are about to perform the operation, which destroys this peak.
peak_indices.erase(k);
// Perform the operation as described in the problem:
// Replace A[k] with min(A[k-1], A[k+1]) - 1.
ll val_left = A[k-1]; // Value of the left neighbor.
ll val_right = A[k+1]; // Value of the right neighbor.
// The new value for A[k] is one less than the minimum of its neighbors.
A[k] = min(val_left, val_right) - 1;
total_ops++; // Increment the total operations counter.
// After modifying A[k], the peak conditions for indices k-1, k, and k+1 might have changed.
// We need to re-evaluate these indices and update their status in the peak set and worklist.
// `update_peak_status` function handles boundaries and updates correctly.
update_peak_status(k - 1); // Check and update status for the element to the left of the original peak's left neighbor. Its peak condition depends on A[k-1]. The triplet is (A[k-2], A[k-1], A[k]). A[k] changed value.
update_peak_status(k); // Check and update status for index k itself. After the operation, A[k] is guaranteed not to be a peak because A[k] < A[k-1] and A[k] < A[k+1]. This call ensures it's removed from the set if somehow it was still there.
update_peak_status(k + 1); // Check and update status for the element to the right of the original peak. Its peak condition depends on A[k]. The triplet is (A[k], A[k+1], A[k+2]). A[k] changed value.
}
// After the loop finishes (no more peaks can be processed), output the total count of operations.
cout << total_ops << endl;
return 0;
}
qwewe