You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
#define lowbit(x) (x & -x)
|
|
|
|
|
const int N = 1e5 + 10;
|
|
|
|
|
|
|
|
|
|
int n, a[N];
|
|
|
|
|
//树状数组
|
|
|
|
|
int tr[N];
|
|
|
|
|
//离散化数组,提供指定值对应的排名,辅助树状数组
|
|
|
|
|
vector<int> b;
|
|
|
|
|
int res; //结果
|
|
|
|
|
|
|
|
|
|
//计算x值在原序列中的排名
|
|
|
|
|
int get(int x) {
|
|
|
|
|
return lower_bound(b.begin(), b.end(), x) - b.begin() + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//求tr[1]~tr[i]的最大值
|
|
|
|
|
int query(int i) {
|
|
|
|
|
int s = 0;
|
|
|
|
|
for (; i; i -= lowbit(i)) s = max(s, tr[i]);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//单点更新x
|
|
|
|
|
void update(int i, int x) {
|
|
|
|
|
for (; i <= n; i += lowbit(i)) tr[i] = max(tr[i], x); //注意这里是跳着取max,不是传统的sum求和
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
scanf("%d", &n);
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
scanf("%d", &a[i]);
|
|
|
|
|
b.push_back(a[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//离散化,用于存储a数组按值由小到大去重排序的结果,这样就可以使用二分查找 值->排名
|
|
|
|
|
sort(b.begin(), b.end());
|
|
|
|
|
b.erase(unique(b.begin(), b.end()), b.end());
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i <= n; i++) { //按原输入序进行遍历,这样才符合LIS的要求
|
|
|
|
|
int k = get(a[i]); //获取值a[i]的整体大小排名k
|
|
|
|
|
int t = query(k - 1) + 1; //在树状数组中查找排名为k-1的最大数量,再加1才是当前连接上后的数量
|
|
|
|
|
update(k, t); //将排名k更新目前最优解t
|
|
|
|
|
}
|
|
|
|
|
//输出
|
|
|
|
|
printf("%d\n", query(b.size()));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|