#include <bits/stdc++.h>
using namespace std;
int solve(int n, vector <int> &a) {
int pw = 2, lg = 1;
while (pw < n) {
pw *= 2;
lg++;
}
vector <int> incr, incrVal, ptr(n, -1);
auto firstGreaterIdx = [&](int v) {
int posIncr = upper_bound(incrVal.rbegin(), incrVal.rend(), v) - incrVal.rbegin();
return (int) incr.size() - 1 - posIncr;
};
for (int i = n - 1; i >= 0; i--) {
if (i < n - 1) {
int posIncr = firstGreaterIdx(a[i]);
if (posIncr >= 0) {
ptr[i] = incr[posIncr];
}
}
while (!incr.empty() && incrVal.back() <= a[i]) {
incr.pop_back();
incrVal.pop_back();
}
incr.push_back(i);
incrVal.push_back(a[i]);
}
vector <int> ptrLen(n, 1), ptrEnd(n);
for (int i = n - 1; i >= 0; i--) {
if (ptr[i] != -1) {
ptrLen[i] = 1 + ptrLen[ptr[i]];
ptrEnd[i] = ptrEnd[ptr[i]];
} else {
ptrEnd[i] = a[i];
}
}
vector <vector<int>> jump(lg, vector <int> (n, -1));
jump[0] = ptr;
for (int l = 1; l < lg; l++) for (int i = 0; i < n; i++) {
int j = jump[l - 1][i];
if (j != -1) {
jump[l][i] = jump[l - 1][j];
}
}
int ans = ptrLen[0];
for (int i = 1; i < n; i++) {
int ansHere = ptrLen[i], last = ptrEnd[i];
if (last < incrVal[0]) {
int posIncr = firstGreaterIdx(last);
int pos = incr[posIncr];
if (pos < i) {
ansHere++;
for (int l = lg - 1; l >= 0; l--) {
int posJump = jump[l][pos];
if (posJump != -1 && posJump < i) {
ansHere += 1 << l;
pos = posJump;
}
}
}
}
ans = max(ans, ansHere);
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false);
int n;
cin >> n;
vector <int> a(n);
for (int &ai : a) {
cin >> ai;
}
cout << solve(n, a);
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 | #include <bits/stdc++.h> using namespace std; int solve(int n, vector <int> &a) { int pw = 2, lg = 1; while (pw < n) { pw *= 2; lg++; } vector <int> incr, incrVal, ptr(n, -1); auto firstGreaterIdx = [&](int v) { int posIncr = upper_bound(incrVal.rbegin(), incrVal.rend(), v) - incrVal.rbegin(); return (int) incr.size() - 1 - posIncr; }; for (int i = n - 1; i >= 0; i--) { if (i < n - 1) { int posIncr = firstGreaterIdx(a[i]); if (posIncr >= 0) { ptr[i] = incr[posIncr]; } } while (!incr.empty() && incrVal.back() <= a[i]) { incr.pop_back(); incrVal.pop_back(); } incr.push_back(i); incrVal.push_back(a[i]); } vector <int> ptrLen(n, 1), ptrEnd(n); for (int i = n - 1; i >= 0; i--) { if (ptr[i] != -1) { ptrLen[i] = 1 + ptrLen[ptr[i]]; ptrEnd[i] = ptrEnd[ptr[i]]; } else { ptrEnd[i] = a[i]; } } vector <vector<int>> jump(lg, vector <int> (n, -1)); jump[0] = ptr; for (int l = 1; l < lg; l++) for (int i = 0; i < n; i++) { int j = jump[l - 1][i]; if (j != -1) { jump[l][i] = jump[l - 1][j]; } } int ans = ptrLen[0]; for (int i = 1; i < n; i++) { int ansHere = ptrLen[i], last = ptrEnd[i]; if (last < incrVal[0]) { int posIncr = firstGreaterIdx(last); int pos = incr[posIncr]; if (pos < i) { ansHere++; for (int l = lg - 1; l >= 0; l--) { int posJump = jump[l][pos]; if (posJump != -1 && posJump < i) { ansHere += 1 << l; pos = posJump; } } } } ans = max(ans, ansHere); } return ans; } int main() { ios_base::sync_with_stdio(false); int n; cin >> n; vector <int> a(n); for (int &ai : a) { cin >> ai; } cout << solve(n, a); return 0; } |
English