#樹狀陣列,離散#C 波動序列
阿新 • • 發佈:2020-10-13
分析
設\(dp[i][j][0/1/2/3]\)表示前\(i\)個位置當前選的數為\(j\),
且選擇的是第一行/第二行/第三行不下降/第三行不上升,
狀態轉移方程顯然,用線段樹或者樹狀陣列維護一下就可以了
程式碼
#include <cstdio> #include <cctype> #include <algorithm> #define rr register using namespace std; const int N = 100011; int n, m, a[3][N], b[N * 3]; inline signed iut() { rr int ans = 0, f = 1; rr char c = getchar(); while (!isdigit(c)) f = (c == '-') ? -f : f, c = getchar(); while (isdigit(c)) ans = (ans << 3) + (ans << 1) + (c ^ 48), c = getchar(); return ans * f; } inline signed max(int a, int b) { return a > b ? a : b; } inline signed fan(int now) { return m - now + 1; } struct Tree_Array { int c[N * 3]; inline void update(int x, int y) { for (; x <= m; x += -x & x) c[x] = max(c[x], y); } inline signed query(int x) { rr int ans = 0; for (; x; x -= -x & x) ans = max(ans, c[x]); return ans; } } h[3][2]; signed main() { freopen("sequence.in", "r", stdin); freopen("sequence.out", "w", stdout); n = iut(); for (rr int i = 1; i <= n; ++i) a[0][i] = iut(), b[++m] = a[0][i]; for (rr int i = 1; i <= n; ++i) a[1][i] = iut(), b[++m] = a[1][i]; for (rr int i = 1; i <= n; ++i) a[2][i] = iut(), b[++m] = a[2][i]; sort(b + 1, b + 1 + m), m = unique(b + 1, b + 1 + m) - b - 1; for (rr int i = 1; i <= n; ++i) a[0][i] = lower_bound(b + 1, b + 1 + m, a[0][i]) - b, a[1][i] = lower_bound(b + 1, b + 1 + m, a[1][i]) - b, a[2][i] = lower_bound(b + 1, b + 1 + m, a[2][i]) - b; for (rr int i = 1; i <= n; ++i) { rr int f1 = max(h[0][0].query(a[0][i]), max(h[1][0].query(a[0][i]), h[2][0].query(a[0][i]))) + 1; rr int f2 = max(h[0][1].query(fan(a[1][i])), max(h[1][1].query(fan(a[1][i])), h[2][1].query(fan(a[1][i])))) + 1; rr int f3 = max(h[0][0].query(a[2][i]), h[1][0].query(a[2][i])) + 1,//一直不下降 f4 = max(h[0][1].query(fan(a[2][i])), h[2][1].query(fan(a[2][i]))) + 1;//一直不上升 h[0][0].update(a[0][i], f1), h[0][1].update(fan(a[0][i]), f1), h[0][0].update(a[1][i], f2), h[0][1].update(fan(a[1][i]), f2), h[1][0].update(a[2][i], f3), h[1][1].update(fan(a[2][i]), f3), h[2][0].update(a[2][i], f4), h[2][1].update(fan(a[2][i]), f4); } return !printf("%d", max(h[0][0].query(m), max(h[1][0].query(m), h[2][0].query(m)))); }