#include <iostream>
#include <vector>
#include <algorithm>
const int MAX_N = 1000 * 1000 + 5;
int reviews[MAX_N];
int reversed_reviews[MAX_N];
using namespace std;
long long sum_arithmetic(long long first, long long step, long long count) {
return (2 * first + (count - 1) * step) * count / 2;
}
long long find_possible_intervals(int left_border, int right_border, int left_pivot, int right_pivot, int k) {
long long result = 0;
int left_margin = left_border - left_pivot;
int right_margin = right_pivot - right_border;
int bigger_margin = max(left_margin, right_margin);
int smaller_margin = min(left_margin, right_margin);
if (k > bigger_margin) {
result += sum_arithmetic(smaller_margin, -1, min(k - bigger_margin, smaller_margin));
k = bigger_margin;
}
if (k >= smaller_margin) {
result += sum_arithmetic(smaller_margin + 1, 0, k - smaller_margin + 1);
k = smaller_margin - 1;
}
if (k >= 0) {
result += sum_arithmetic(1, 1, k + 1);
}
return result;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
long long result = 0;
int left_border = 0;
int right_border = 0;
for (int i = 0; i < n; i++) {
cin >> reviews[i];
reversed_reviews[reviews[i]] = i;
if (reviews[i] == n) {
left_border = i;
right_border = i;
}
}
for (int smallest = n; smallest >= 1; smallest--) {
left_border = min(reversed_reviews[smallest], left_border);
right_border = max(reversed_reviews[smallest], right_border);
// cout << smallest << ": " << left_border << " " << right_border << "\n";
if (smallest > 1 && left_border <= reversed_reviews[smallest - 1]
&& reversed_reviews[smallest - 1] <= right_border) {
continue;
}
int left_pivot = 0;
int right_pivot = n - 1;
if (smallest > 1) {
if (reversed_reviews[smallest - 1] < left_border) {
left_pivot = reversed_reviews[smallest - 1] + 1;
}
else {
right_pivot = reversed_reviews[smallest - 1] - 1;
}
}
int in_proper_interval = n - smallest + 1;
int possible_other = in_proper_interval - 1;
int total_interval_length = right_border - left_border + 1;
int k = possible_other - (total_interval_length - in_proper_interval);
result += find_possible_intervals(left_border, right_border,left_pivot, right_pivot, k);
// cout << find_possible_intervals(left_border, right_border,left_pivot, right_pivot, k) << "\n";
}
cout << n + 1 + n << " " << result;
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include <iostream> #include <vector> #include <algorithm> const int MAX_N = 1000 * 1000 + 5; int reviews[MAX_N]; int reversed_reviews[MAX_N]; using namespace std; long long sum_arithmetic(long long first, long long step, long long count) { return (2 * first + (count - 1) * step) * count / 2; } long long find_possible_intervals(int left_border, int right_border, int left_pivot, int right_pivot, int k) { long long result = 0; int left_margin = left_border - left_pivot; int right_margin = right_pivot - right_border; int bigger_margin = max(left_margin, right_margin); int smaller_margin = min(left_margin, right_margin); if (k > bigger_margin) { result += sum_arithmetic(smaller_margin, -1, min(k - bigger_margin, smaller_margin)); k = bigger_margin; } if (k >= smaller_margin) { result += sum_arithmetic(smaller_margin + 1, 0, k - smaller_margin + 1); k = smaller_margin - 1; } if (k >= 0) { result += sum_arithmetic(1, 1, k + 1); } return result; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; long long result = 0; int left_border = 0; int right_border = 0; for (int i = 0; i < n; i++) { cin >> reviews[i]; reversed_reviews[reviews[i]] = i; if (reviews[i] == n) { left_border = i; right_border = i; } } for (int smallest = n; smallest >= 1; smallest--) { left_border = min(reversed_reviews[smallest], left_border); right_border = max(reversed_reviews[smallest], right_border); // cout << smallest << ": " << left_border << " " << right_border << "\n"; if (smallest > 1 && left_border <= reversed_reviews[smallest - 1] && reversed_reviews[smallest - 1] <= right_border) { continue; } int left_pivot = 0; int right_pivot = n - 1; if (smallest > 1) { if (reversed_reviews[smallest - 1] < left_border) { left_pivot = reversed_reviews[smallest - 1] + 1; } else { right_pivot = reversed_reviews[smallest - 1] - 1; } } int in_proper_interval = n - smallest + 1; int possible_other = in_proper_interval - 1; int total_interval_length = right_border - left_border + 1; int k = possible_other - (total_interval_length - in_proper_interval); result += find_possible_intervals(left_border, right_border,left_pivot, right_pivot, k); // cout << find_possible_intervals(left_border, right_border,left_pivot, right_pivot, k) << "\n"; } cout << n + 1 + n << " " << result; return 0; } |
English