#include <stdlib.h> #include <algorithm> #include <cassert> #include <cstdio> #include <vector> using namespace std; const int MAXN = 1000000 + 1; typedef long long LL; int n; int a[MAXN]; int pos[MAXN]; int left_max[MAXN]; int right_max[MAXN]; int rev_right_max[MAXN]; LL f() { LL res = 0; for (int i = 0; i < n; i++) { pos[a[i]] = i; rev_right_max[i + 1] = n; if (i == 0 || a[i] > left_max[i - 1]) { left_max[i] = a[i]; } else { left_max[i] = left_max[i - 1]; } } for (int i = n - 1; i >= 0; i--) { if (i == n - 1 || a[i] > right_max[i + 1]) { right_max[i] = a[i]; } else { right_max[i] = right_max[i + 1]; } rev_right_max[right_max[i]] = i; } for (int i = 2; i <= n; i++) { if (rev_right_max[i] == n) rev_right_max[i] = rev_right_max[i - 1]; } for (int idx = 0; idx < n; idx++) { int i = left_max[idx]; if (left_max[idx] > i) { continue; } int j = n; while (j > idx + 2 && a[j - 1] < i) j--; if (idx >= n - 2) { j = n; } else { j = max(idx + 2, rev_right_max[i]); } int len = n - j; assert(len >= 0); int min_count = 2 * (i - ((n) / 2)) + 1; if (n % 2) min_count--; min_count = max(0, min_count); min_count -= idx + 1; min_count = max(0, min_count); int added = max(0, (len + 1 - min_count)); res += added; } return res; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); LL res = f(); reverse(a, a + n); res += f(); printf("%d %lld\n", 2 * n + 1, res + 1); }
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 | #include <stdlib.h> #include <algorithm> #include <cassert> #include <cstdio> #include <vector> using namespace std; const int MAXN = 1000000 + 1; typedef long long LL; int n; int a[MAXN]; int pos[MAXN]; int left_max[MAXN]; int right_max[MAXN]; int rev_right_max[MAXN]; LL f() { LL res = 0; for (int i = 0; i < n; i++) { pos[a[i]] = i; rev_right_max[i + 1] = n; if (i == 0 || a[i] > left_max[i - 1]) { left_max[i] = a[i]; } else { left_max[i] = left_max[i - 1]; } } for (int i = n - 1; i >= 0; i--) { if (i == n - 1 || a[i] > right_max[i + 1]) { right_max[i] = a[i]; } else { right_max[i] = right_max[i + 1]; } rev_right_max[right_max[i]] = i; } for (int i = 2; i <= n; i++) { if (rev_right_max[i] == n) rev_right_max[i] = rev_right_max[i - 1]; } for (int idx = 0; idx < n; idx++) { int i = left_max[idx]; if (left_max[idx] > i) { continue; } int j = n; while (j > idx + 2 && a[j - 1] < i) j--; if (idx >= n - 2) { j = n; } else { j = max(idx + 2, rev_right_max[i]); } int len = n - j; assert(len >= 0); int min_count = 2 * (i - ((n) / 2)) + 1; if (n % 2) min_count--; min_count = max(0, min_count); min_count -= idx + 1; min_count = max(0, min_count); int added = max(0, (len + 1 - min_count)); res += added; } return res; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); LL res = f(); reverse(a, a + n); res += f(); printf("%d %lld\n", 2 * n + 1, res + 1); } |