#include <iostream> #include <algorithm> using namespace std; int n; int a[1000002]; // 1..n int rev[1000002]; // 1..n int64_t computePossibilities(int64_t dotsOnLeft, int64_t dotsOnRight, int64_t k) { int64_t mini = min(dotsOnLeft, dotsOnRight); int64_t maxi = max(dotsOnLeft, dotsOnRight); int64_t result = 0; int64_t sum = mini + maxi; int64_t aux; if (dotsOnLeft == 0 || dotsOnRight == 0) { return 1 + min(k, maxi); } // first step: 0 <= k <= mini aux = min(k, mini); result += (aux + 1) * (aux + 2) / 2; if (k <= mini) { return result; } // second step: mini < k <= maxi aux = min(k, maxi); result += (aux - mini) * (mini + 1); if (k <= maxi) { return result; } // third step: maxi < k <= mini + maxi aux = min(k, mini + maxi); result += mini * (mini + 1) / 2; result -= (sum - aux) * (sum - aux + 1) / 2; return result; } int main() { ios_base::sync_with_stdio(0); cin.tie(nullptr); cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; rev[a[i]] = i; } if (n <= 2) { cout << 2 * n + 1 << " " << n << endl; return 0; } int64_t result = 1; // accounting for {1, ..., n} here int L = rev[n], R = rev[n]; for (int i = n - 1; i >= 1; --i) { // NOT taking i here int badIndex = rev[i]; if (L <= badIndex && badIndex <= R) { // bad index inside of currently considered interval continue; } if (R - L > 2 * (n - i - 1)) { // currently considered interval is too large if (badIndex < L) { L = badIndex; } else { R = badIndex; } continue; } // std::cout << "for i = " << i << " "; int dotsOnLeft = L - 1, dotsOnRight = n - R; if (badIndex < L) { dotsOnLeft = L - badIndex - 1; } else { dotsOnRight = badIndex - R - 1; } int dotsToAccomodateAtMax = 2 * n - 2 * i - 2 - R + L; result += computePossibilities(dotsOnLeft, dotsOnRight, dotsToAccomodateAtMax); // std::cout << "L = " << L << " R = " << R << " "; // std::cout << "(dotsLeft, dotsRight, k) = " << "(" << dotsOnLeft << ", " << dotsOnRight << ", " << dotsToAccomodateAtMax << ")"; // std::cout << " we add " << computePossibilities(dotsOnLeft, dotsOnRight, dotsToAccomodateAtMax) << std::endl; if (badIndex < L) { L = badIndex; } else { R = badIndex; } } cout << 2 * n + 1 << " " << result << endl; 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 | #include <iostream> #include <algorithm> using namespace std; int n; int a[1000002]; // 1..n int rev[1000002]; // 1..n int64_t computePossibilities(int64_t dotsOnLeft, int64_t dotsOnRight, int64_t k) { int64_t mini = min(dotsOnLeft, dotsOnRight); int64_t maxi = max(dotsOnLeft, dotsOnRight); int64_t result = 0; int64_t sum = mini + maxi; int64_t aux; if (dotsOnLeft == 0 || dotsOnRight == 0) { return 1 + min(k, maxi); } // first step: 0 <= k <= mini aux = min(k, mini); result += (aux + 1) * (aux + 2) / 2; if (k <= mini) { return result; } // second step: mini < k <= maxi aux = min(k, maxi); result += (aux - mini) * (mini + 1); if (k <= maxi) { return result; } // third step: maxi < k <= mini + maxi aux = min(k, mini + maxi); result += mini * (mini + 1) / 2; result -= (sum - aux) * (sum - aux + 1) / 2; return result; } int main() { ios_base::sync_with_stdio(0); cin.tie(nullptr); cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; rev[a[i]] = i; } if (n <= 2) { cout << 2 * n + 1 << " " << n << endl; return 0; } int64_t result = 1; // accounting for {1, ..., n} here int L = rev[n], R = rev[n]; for (int i = n - 1; i >= 1; --i) { // NOT taking i here int badIndex = rev[i]; if (L <= badIndex && badIndex <= R) { // bad index inside of currently considered interval continue; } if (R - L > 2 * (n - i - 1)) { // currently considered interval is too large if (badIndex < L) { L = badIndex; } else { R = badIndex; } continue; } // std::cout << "for i = " << i << " "; int dotsOnLeft = L - 1, dotsOnRight = n - R; if (badIndex < L) { dotsOnLeft = L - badIndex - 1; } else { dotsOnRight = badIndex - R - 1; } int dotsToAccomodateAtMax = 2 * n - 2 * i - 2 - R + L; result += computePossibilities(dotsOnLeft, dotsOnRight, dotsToAccomodateAtMax); // std::cout << "L = " << L << " R = " << R << " "; // std::cout << "(dotsLeft, dotsRight, k) = " << "(" << dotsOnLeft << ", " << dotsOnRight << ", " << dotsToAccomodateAtMax << ")"; // std::cout << " we add " << computePossibilities(dotsOnLeft, dotsOnRight, dotsToAccomodateAtMax) << std::endl; if (badIndex < L) { L = badIndex; } else { R = badIndex; } } cout << 2 * n + 1 << " " << result << endl; return 0; } |