// clang-format off
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
#define FOR(i,l,r) for(auto i=(l);i<=(r);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) int(x.size())
auto operator<<(ostream&o,auto p)->decltype(p.first,o){return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator<<(ostream&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";}
#ifdef DEBUG
#define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n'
#else
#define debug(...) {}
#endif
// clang-format on
class RTree
{
int base = 1;
vector<int> data;
public:
RTree(int n)
{
while (base <= n) base <<= 1;
data.resize(base << 1);
};
void set_atp(int i, int val)
{
data[i + base] = val;
for (int v = (i + base) / 2; v > 0; v >>= 1)
data[v] = max(data[v << 1], data[(v << 1) + 1]);
}
int max_onr(int l, int r)
{
int res = 0;
l += base, r += base;
while (l <= r) {
if (l & 1) res = max(res, data[l++]);
if (!(r & 1)) res = max(res, data[r--]);
l >>= 1, r >>= 1;
}
return res;
}
};
int N, max_val = 0;
vector<int> seq;
vector<int> rst; // greatest i <= n s.t. dp[i - 1] >= dp[n]
void
calc_range_start()
{
rst.resize(N, 0);
RTree last(max_val + 1); // last index+1 per value
REP (n, N) {
rst[n] = last.max_onr(seq[n], max_val);
last.set_atp(seq[n], n + 1);
}
debug(rst);
}
int
dp_brute()
{
RTree dp(N);
REP (n, N) {
int val = dp.max_onr(rst[n], n - 1) + 1;
dp.set_atp(n, val);
}
return dp.max_onr(0, N - 1);
}
int
main()
{
cin.tie(0)->sync_with_stdio(0);
cin >> N;
seq.reserve(N + N);
seq.resize(N);
for (auto &x : seq) cin >> x;
max_val = *max_element(seq.begin(), seq.end());
REP (i, N) seq.emplace_back(seq[i]);
debug(seq);
N += N;
calc_range_start();
cout << dp_brute() << "\n";
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 | // clang-format off #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r) for(auto i=(l);i<=(r);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) int(x.size()) auto operator<<(ostream&o,auto p)->decltype(p.first,o){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(ostream&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";} #ifdef DEBUG #define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n' #else #define debug(...) {} #endif // clang-format on class RTree { int base = 1; vector<int> data; public: RTree(int n) { while (base <= n) base <<= 1; data.resize(base << 1); }; void set_atp(int i, int val) { data[i + base] = val; for (int v = (i + base) / 2; v > 0; v >>= 1) data[v] = max(data[v << 1], data[(v << 1) + 1]); } int max_onr(int l, int r) { int res = 0; l += base, r += base; while (l <= r) { if (l & 1) res = max(res, data[l++]); if (!(r & 1)) res = max(res, data[r--]); l >>= 1, r >>= 1; } return res; } }; int N, max_val = 0; vector<int> seq; vector<int> rst; // greatest i <= n s.t. dp[i - 1] >= dp[n] void calc_range_start() { rst.resize(N, 0); RTree last(max_val + 1); // last index+1 per value REP (n, N) { rst[n] = last.max_onr(seq[n], max_val); last.set_atp(seq[n], n + 1); } debug(rst); } int dp_brute() { RTree dp(N); REP (n, N) { int val = dp.max_onr(rst[n], n - 1) + 1; dp.set_atp(n, val); } return dp.max_onr(0, N - 1); } int main() { cin.tie(0)->sync_with_stdio(0); cin >> N; seq.reserve(N + N); seq.resize(N); for (auto &x : seq) cin >> x; max_val = *max_element(seq.begin(), seq.end()); REP (i, N) seq.emplace_back(seq[i]); debug(seq); N += N; calc_range_start(); cout << dp_brute() << "\n"; return 0; } |
English