[树状数组] aw3662. 最大上升子序列和(LIS优化+树状数组+离散化+好题+aw周赛003_3)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[树状数组] aw3662. 最大上升子序列和(LIS优化+树状数组+离散化+好题+aw周赛003_3)相关的知识,希望对你有一定的参考价值。
1. 题目来源
相关题目:[线性dp] 最大上升子序列和(最长上升子序列模型+经典)
2. 题目解析
LIS
+树状数组+离散化。
看题解就行了:抽风大佬的题解
树状数组已经忘了,应该 2 各月没写相关题目了… 但分析来确实是很经典的优化。
很不错的题目,很综合,很有用!
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)
y总代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int w[N];
LL tr[N];
vector<int> xs;
LL f[N];
int get(int x) {
return lower_bound(xs.begin(), xs.end(), x) - xs.begin() + 1;
}
int lowbit(int x) {
return x & -x;
}
void add(int x, LL v) {
for (int i = x; i <= n; i += lowbit(i))
tr[i] = max(tr[i], v);
}
LL query(int x) {
LL res = 0;
for (int i = x; i; i -= lowbit(i))
res = max(res, tr[i]);
return res;
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) {
scanf("%d", &w[i]);
xs.push_back(w[i]);
}
sort(xs.begin(), xs.end());
xs.erase(unique(xs.begin(), xs.end()), xs.end());
LL res = 0;
for (int i = 0; i < n; i ++ ) {
int k = get(w[i]);
f[i] = query(k - 1) + w[i];
res = max(res, f[i]);
add(k, f[i]);
}
printf("%lld\\n", res);
return 0;
}
以上是关于[树状数组] aw3662. 最大上升子序列和(LIS优化+树状数组+离散化+好题+aw周赛003_3)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ3173: [Tjoi2013]最长上升子序列(树状数组)