Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * author : cr11htxuanson
- * created : 20.09.2018
- **/
- #include <bits/stdc++.h>
- using namespace std;
- const int MAX = 50005;
- const int N = 50050;
- int n;
- int A[N];
- int F[5][N];
- int T[5][4 * N];
- int dp[5][N];
- void Input()
- {
- cin >> n;
- for (int i = 1; i <= n; i++) cin >> A[i];
- }
- void Subtask2()
- {
- memset(F, -1, sizeof(F));
- for (int i = 1; i <= n; i++) F[1][i] = 1;
- for (int i = 2; i <= n; i++) {
- for (int j = 1; j < i; j++) {
- if (A[i] > A[j]) F[1][i] = max(F[1][i], F[1][j] + 1);
- }
- for (int j = 1; j < i; j++) {
- if (A[i] > A[j]) continue;
- if (F[1][j] >= 2) F[2][i] = max(F[2][i], F[1][j] + 1);
- if (F[2][j] != -1) F[2][i] = max(F[2][i], F[2][j] + 1);
- }
- for (int j = 1; j < i; j++) {
- if (A[i] < A[j]) continue;
- if (F[2][j] != -1) F[3][i] = max(F[3][i], F[2][j] + 1);
- if (F[3][j] != -1) F[3][i] = max(F[3][i], F[3][j] + 1);
- }
- for (int j = 1; j < i; j++) {
- if (A[i] > A[j]) continue;
- if (F[3][j] != -1) F[4][i] = max(F[4][i], F[3][j] + 1);
- if (F[4][j] != -1) F[4][i] = max(F[4][i], F[4][j] + 1);
- }
- }
- int ans = 0;
- for (int i = 1; i <= n; i++) ans = max(ans, F[4][i]);
- cout << ans;
- }
- void Roirac()
- {
- map <int, int> Map;
- set <int> Set;
- set <int> :: iterator it;
- for (int i = 1; i <= n; i++) Set.insert(A[i]);
- int cnt = 0;
- for (it = Set.begin(); it != Set.end(); it++) {
- cnt++;
- int val = *it;
- Map[val] = cnt;
- }
- for (int i = 1; i <= n; i++) A[i] = Map[A[i]];
- }
- void update(int id, int node, int l, int r, int ql, int qr, int val)
- {
- if (l > qr || r < ql) return;
- if (l >= ql && r <= qr) {
- T[id][node] = val;
- return;
- }
- int mid = (l + r) >> 1;
- update(id, node + node, l, mid, ql, qr, val);
- update(id, node + node + 1, mid + 1, r, ql, qr, val);
- T[id][node] = max(T[id][node + node], T[id][node + node + 1]);
- }
- int get(int id, int node, int l, int r, int ql, int qr)
- {
- if (l > qr || r < ql) return 0;
- if (l >= ql && r <= qr) return T[id][node];
- int mid = (l + r) >> 1;
- int x = get(id, node + node, l, mid, ql, qr);
- int y = get(id, node + node + 1, mid + 1, r, ql, qr);
- return max(x, y);
- }
- void Lastsub()
- {
- Roirac();
- memset(T, -1, sizeof(T));
- for (int i = 2; i <= n; i++) {
- int val_1 = get(1, 1, 1, n, 1, A[i] - 1);
- int val_2 = max(get(1, 1, 1, n, A[i] + 1, MAX), get(2, 1, 1, n, A[i] + 1, MAX));
- int val_3 = max(get(2, 1, 1, n, 1, A[i] - 1), get(3, 1, 1, n, 1, A[i] - 1));
- int val_4 = max(get(3, 1, 1, n, A[i] + 1, MAX), get(4, 1, 1, n, A[i] + 1, MAX));
- dp[1][i] = val_1 + 1;
- if (val_2 >= 2) dp[2][i] = val_2 + 1;
- if (val_3 >= 3) dp[3][i] = val_3 + 1;
- if (val_4 >= 4) dp[4][i] = val_4 + 1;
- update(1, 1, 1, n, A[i], A[i], dp[1][i]);
- update(2, 1, 1, n, A[i], A[i], dp[2][i]);
- update(3, 1, 1, n, A[i], A[i], dp[3][i]);
- update(4, 1, 1, n, A[i], A[i], dp[4][i]);
- }
- int ans = 0;
- for (int i = 1; i <= n; i++) ans = max(ans, dp[4][i]);
- cout << ans;
- }
- void Output()
- {
- // /Subtask2();
- if (n <= 1000) {
- Subtask2();
- return;
- }
- Lastsub();
- }
- int main()
- {
- ios :: sync_with_stdio(false);
- cin.tie(0); cout.tie(0);
- // freopen ("M.inp", "r", stdin);
- // freopen ("M.out", "w", stdout);
- Input(); Output();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement