#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; } |