标签:训练 include define strong etl clu first 数组 严格
给定一个序列\(A\),请你从中取出一个最长的子序列,满足子序列的奇数项都严格大于偶数项或都严格小于偶数项。
- \(dp[i][0..1][0..1]\)表示当前为第\(i\)项,为选出子序列的奇数项还是偶数项,选择第一个决策还是第二个决策。
- 可以发现\(DP\)方程满足之和前缀\(Max{dp}\)和后缀\(Max{dp}\)。
- 用树状数组优化。
#include <bits/stdc++.h>
#define REP(i, s, t) for (int i = s; i <= t; i++)
#define PER(i, s, t) for (int i = s; i >= t; i--)
#define FI first
#define SE second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template <class T>
void chkmax(T& x, T y) {
x = max(x, y);
}
template <class T>
void chkmin(T& x, T y) {
x = min(x, y);
}
template <class T>
void re(T& x) {
x = 0;
char ch = 0;
int f = 1;
for (; !isdigit(ch); ch = getchar())
if (ch == '-')
f = -1;
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
x *= f;
}
const int N = 1e5 + 5;
const int M = 1e6 + 5;
int n;
int a[N];
pii merge(pii a, pii b) { return mp(max(a.FI, b.FI), max(a.SE, b.SE)); }
struct fenwick {
int lowbit(int x) { return x & -x; }
pii tr[M][2];
int lim;
void setLim(int L) { lim = L; }
void modify(int p, pii v0, pii v1) {
for (; p <= lim; p += lowbit(p)) {
tr[p][0] = merge(tr[p][0], v0);
tr[p][1] = merge(tr[p][1], v1);
}
}
pii query0(int p) {
pii ans = mp(0, 0);
for (; p; p -= lowbit(p)) ans = merge(ans, tr[p][0]);
return ans;
}
pii query1(int p) {
pii ans = mp(0, 0);
for (; p; p -= lowbit(p)) ans = merge(ans, tr[p][1]);
return ans;
}
} bit1, bit2;
// bit1 maintain prefix dp max
// bit2 maintain suffix dp max
int dp[N][2][2];
int mx, ans;
int main() {
freopen("jump.in", "r", stdin);
freopen("jump.out", "w", stdout);
re(n);
for (int i = 1; i <= n; i++) re(a[i]), a[i]++, mx = max(mx, a[i]);
bit1.setLim(mx), bit2.setLim(mx);
for (int i = 1; i <= n; i++) {
pii tmp1 = bit1.query0(a[i] - 1), tmp2 = bit1.query1(a[i] - 1);
pii tmp3 = bit2.query0(mx - a[i]), tmp4 = bit2.query1(mx - a[i]);
dp[i][0][0] = tmp1.SE + 1;
dp[i][1][0] = tmp3.FI + 1;
dp[i][0][1] = tmp4.SE + 1;
dp[i][1][1] = tmp2.FI + 1;
bit1.modify(a[i], mp(dp[i][0][0], dp[i][1][0]), mp(dp[i][0][1], dp[i][1][1]));
bit2.modify(mx - a[i] + 1, mp(dp[i][0][0], dp[i][1][0]), mp(dp[i][0][1], dp[i][1][1]));
dp[i][0][0] = dp[i][0][1] = 1;
bit1.modify(a[i], mp(1, 0), mp(1, 0));
bit2.modify(mx - a[i] + 1, mp(1, 0), mp(1, 0));
}
ans = 0;
for (int i = 1; i <= n; i++)
chkmax(ans, max(max(dp[i][0][0], dp[i][0][1]), max(dp[i][1][0], dp[i][1][1])));
printf("%d\n", ans);
return 0;
}
标签:训练 include define strong etl clu first 数组 严格
原文地址:https://www.cnblogs.com/chhokmah/p/11865705.html