CSES - Shared codeLink to this code:
https://cses.fi/paste/a411f61bcb5393bd38b66e/
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cmath>
using ll = long long;
class SegmentTree{
private:
std::vector<int> aint;
int n;
int join(int x, int y) {
return std::max(x, y);
}
void _update(int node, int from, int to, int x, int val) {
if(from < to) {
int mid = (from + to) / 2;
if(x <= mid)
_update(node * 2, from, mid, x, val);
else
_update(node * 2 + 1, mid + 1, to, x, val);
aint[node] = join(aint[node * 2], aint[node * 2 + 1]);
} else
aint[node] = val;
}
int _query(int node, int from, int to, int x, int y) {
if(from == x && to == y) {
return aint[node];
} else {
int mid = (from + to) / 2;
if(x <= mid && y <= mid)
return _query(node * 2, from, mid, x, y);
else if(mid + 1 <= x && mid + 1 <= y)
return _query(node * 2 + 1, mid + 1, to, x, y);
else
return join(_query(node * 2, from, mid, x, mid),
_query(node * 2 + 1, mid + 1, to, mid + 1, y));
}
}
void _print(int node, int from, int to) {
if(from < to) {
int mid = (from + to) / 2;
_print(node * 2, from, mid);
_print(node * 2 + 1, mid + 1, to);
} else
std::cout << aint[node] << " ";
}
public:
SegmentTree(int n_) {
n = n_;
aint.resize(1 + 4 * n);
}
void update(int x, int val) {
_update(1, 1, n, x, val);
}
int query(int x, int y) {
return _query(1, 1, n, x, y);
}
void print() {
std::cout << "Print array\n";
_print(1, 1, n);
std::cout << '\n';
}
};
/*
One easy way to normalize an array is to first create a copy of it.
Let 'v' be the array to be normalized and 'aux' its duplicate.
Then, sort the copy and erase the dublicates.
Thus, 'aux' contains all the distinct elements in 'v'.
Now, we simply have to find for each element in 'v' its position in 'aux'.
This can be easily done using binary search or the STL-provided lower_bound function.
*/
void normalize(std::vector<int> &v) {
std::vector<int> aux = v;
std::sort(aux.begin(), aux.end());
aux.erase(std::unique(aux.begin(), aux.end()), aux.end());
for(int i = 0; i < v.size(); i++)
v[i] = std::lower_bound(aux.begin(), aux.end(), v[i]) - aux.begin() + 1;
}
int main() {
int n;
std::cin >> n;
std::vector<int> v(n);
for(int i = 0; i < n; i++)
std::cin >> v[i];
normalize(v);
SegmentTree segTree(n);
for(int i = 0; i < n; i++) {
int result = 0;
if(1 < v[i])
result = segTree.query(1, v[i] - 1);
else
result = 0;
segTree.update(v[i], result + 1);
}
std::cout << segTree.query(1, n) << '\n';
return 0;
}