Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define F first
- #define S second
- //#define mp make_pair
- #define pb push_back
- #define loop(i,x,y) for(int i=x;i<=y;i++)
- using namespace std;
- typedef long long ll;
- const int N = 1e3 + 9;
- const int MOD = 1e9 + 7;
- const int INF = 1e7;
- int prefixSum[N], dp[N][N], segTree[2][N][4 * N], A[N], prevOdd[N], nextOdd[N];
- void build (int v, int l, int r, int x, int y) {
- if (l == r) {
- segTree[x][y][v] = -INF;
- return;
- }
- int mid = (l + r) / 2;
- build (2 * v, l, mid, x, y);
- build (2 * v + 1, mid + 1, r, x, y);
- segTree[x][y][v] = max (segTree[x][y][2 * v], segTree[x][y][2 * v + 1]);
- return;
- }
- void updateTree (int v, int l, int r, int idx, int val, int x, int y) {
- if (l == r) {
- segTree[x][y][v] = val;
- return;
- }
- int mid = (l + r) / 2;
- if (idx <= mid)
- updateTree (2 * v, l, mid, idx, val, x, y);
- else updateTree (2 * v + 1, mid + 1, r, idx, val, x, y);
- segTree[x][y][v] = max (segTree[x][y][2 * v], segTree[x][y][2 * v + 1]);
- return;
- }
- int getMax (int v, int l, int r, int L, int R, int x, int y) {
- if (L <= l && r <= R)
- return segTree[x][y][v];
- if (l > R || r < L)
- return -INF;
- int mid = (l + r) / 2;
- int Q1 = getMax (2 * v, l, mid, L, R, x, y);
- int Q2 = getMax (2 * v + 1, mid + 1, r, L, R, x, y);
- return max (Q1, Q2);
- }
- int main () {
- int n, firstOdd = -1, lastOdd = -1;
- cin >> n;
- for (int i = 1; i <= n; i++) {
- cin >> A[i];
- prefixSum[i] = prefixSum[i - 1] + A[i];
- build (1, 1, n, 0, i);
- build (1, 1, n, 1, i);
- }
- int last = 0;
- for (int i = 1; i <= n; i++) {
- if (last)
- prevOdd[i] = last;
- else prevOdd[i] = 0;
- if (A[i] & 1) {
- last = i;
- if (firstOdd == -1)
- firstOdd = i;
- }
- }
- last = 0;
- for (int i = n; i >= 1; i--) {
- if (last)
- nextOdd[i] = last;
- else nextOdd[i] = n + 1;
- if (A[i] & 1) {
- last = i;
- if (lastOdd == -1)
- lastOdd = i;
- }
- }
- dp[1][n] = prefixSum[n];
- updateTree (1, 1, n, 1, dp[1][n], 1, n);
- updateTree (1, 1, n, n, dp[1][n], 0, 1);
- for (int len = n - 1; len >= 1; len--) {
- for (int l = 1; l + len - 1 <= n; l++) {
- int r = l + len - 1;
- if (r >= lastOdd && l <= firstOdd) {
- dp[l][r] = prefixSum[r] - prefixSum[l - 1];
- updateTree (1, 1, n, r, dp[l][r], 0, l);
- updateTree (1, 1, n, l, dp[l][r], 1, r);
- //cout << l << ' ' << r << ' ' << dp[l][r] << "\n";
- continue;
- }
- int bestBelowFloor = -INF;
- if (r < lastOdd)
- bestBelowFloor = max (bestBelowFloor, getMax (1, 1, n, nextOdd[r], nextOdd[nextOdd[r]] - 1, 0, l));
- if (l > firstOdd)
- bestBelowFloor = max (bestBelowFloor, getMax (1, 1, n, prevOdd[prevOdd[l]] + 1, prevOdd[l], 1, r));
- dp[l][r] = prefixSum[r] - prefixSum[l - 1] + bestBelowFloor;
- updateTree (1, 1, n, r, dp[l][r], 0, l);
- updateTree (1, 1, n, l, dp[l][r], 1, r);
- //cout << l << ' ' << r << ' ' << dp[l][r] << "\n";
- }
- }
- int res = -INF;
- for (int l = 1; l <= n; l++) {
- int c = 0;
- for (int r = l; r <= n; r++) {
- if (A[r] & 1)
- c++;
- if (((prefixSum[r] - prefixSum[l - 1]) & 1) && c == 1)
- res = max (res, dp[l][r]);
- }
- }
- if (res == -INF)
- cout << -1 << "\n";
- else cout << res << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment