Advertisement
Fshl0

Untitled

Jan 7th, 2022
1,305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.29 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define F first
  3. #define S second
  4. //#define mp make_pair
  5. #define pb push_back
  6. #define loop(i,x,y) for(int i=x;i<=y;i++)
  7.  
  8. using namespace std;
  9. typedef long long ll;
  10.  
  11. const int N = 1e3 + 9;
  12. const int MOD = 1e9 + 7;
  13. const int INF = 1e7;
  14.  
  15. int prefixSum[N], dp[N][N], segTree[2][N][4 * N], A[N], prevOdd[N], nextOdd[N];
  16.  
  17. void build (int v, int l, int r, int x, int y) {
  18.     if (l == r) {
  19.         segTree[x][y][v] = -INF;
  20.        
  21.         return;
  22.     }
  23.    
  24.     int mid = (l + r) / 2;
  25.     build (2 * v, l, mid, x, y);
  26.     build (2 * v + 1, mid + 1, r, x, y);
  27.    
  28.     segTree[x][y][v] = max (segTree[x][y][2 * v], segTree[x][y][2 * v + 1]);
  29.     return;
  30. }
  31.  
  32. void updateTree (int v, int l, int r, int idx, int val, int x, int y) {
  33.     if (l == r) {
  34.         segTree[x][y][v] = val;
  35.        
  36.         return;
  37.     }
  38.    
  39.     int mid = (l + r) / 2;
  40.    
  41.     if (idx <= mid)
  42.         updateTree (2 * v, l, mid, idx, val, x, y);
  43.     else updateTree (2 * v + 1, mid + 1, r, idx, val, x, y);
  44.    
  45.     segTree[x][y][v] = max (segTree[x][y][2 * v], segTree[x][y][2 * v + 1]);
  46.     return;
  47. }
  48.  
  49. int getMax (int v, int l, int r, int L, int R, int x, int y) {
  50.     if (L <= l && r <= R)
  51.         return segTree[x][y][v];
  52.    
  53.     if (l > R || r < L)
  54.         return -INF;
  55.    
  56.     int mid = (l + r) / 2;
  57.     int Q1 = getMax (2 * v, l, mid, L, R, x, y);
  58.     int Q2 = getMax (2 * v + 1, mid + 1, r, L, R, x, y);
  59.    
  60.     return max (Q1, Q2);
  61. }
  62.  
  63. int main () {
  64.     int n, firstOdd = -1, lastOdd = -1;
  65.     cin >> n;
  66.    
  67.     for (int i = 1; i <= n; i++) {
  68.         cin >> A[i];
  69.         prefixSum[i] = prefixSum[i - 1] + A[i];
  70.        
  71.         build (1, 1, n, 0, i);
  72.         build (1, 1, n, 1, i);
  73.     }
  74.    
  75.     int last = 0;
  76.     for (int i = 1; i <= n; i++) {
  77.         if (last)
  78.             prevOdd[i] = last;
  79.         else prevOdd[i] = 0;
  80.        
  81.         if (A[i] & 1) {
  82.             last = i;
  83.            
  84.             if (firstOdd == -1)
  85.                 firstOdd = i;
  86.         }
  87.     }
  88.    
  89.     last = 0;
  90.     for (int i = n; i >= 1; i--) {
  91.         if (last)
  92.             nextOdd[i] = last;
  93.         else nextOdd[i] = n + 1;
  94.        
  95.         if (A[i] & 1) {
  96.             last = i;
  97.            
  98.             if (lastOdd == -1)
  99.                 lastOdd = i;
  100.         }
  101.     }
  102.    
  103.     dp[1][n] = prefixSum[n];
  104.     updateTree (1, 1, n, 1, dp[1][n], 1, n);
  105.     updateTree (1, 1, n, n, dp[1][n], 0, 1);
  106.    
  107.     for (int len = n - 1; len >= 1; len--) {
  108.         for (int l = 1; l + len - 1 <= n; l++) {
  109.             int r = l + len - 1;
  110.            
  111.             if (r >= lastOdd && l <= firstOdd) {
  112.                 dp[l][r] = prefixSum[r] - prefixSum[l - 1];
  113.                
  114.                 updateTree (1, 1, n, r, dp[l][r], 0, l);
  115.                 updateTree (1, 1, n, l, dp[l][r], 1, r);
  116.                
  117.                 //cout << l << ' ' << r << ' ' << dp[l][r] << "\n";
  118.                 continue;
  119.             }
  120.            
  121.             int bestBelowFloor = -INF;
  122.            
  123.             if (r < lastOdd)
  124.                 bestBelowFloor = max (bestBelowFloor, getMax (1, 1, n, nextOdd[r], nextOdd[nextOdd[r]] - 1, 0, l));
  125.            
  126.             if (l > firstOdd)
  127.                 bestBelowFloor = max (bestBelowFloor, getMax (1, 1, n, prevOdd[prevOdd[l]] + 1, prevOdd[l], 1, r));
  128.            
  129.             dp[l][r] = prefixSum[r] - prefixSum[l - 1] + bestBelowFloor;
  130.            
  131.             updateTree (1, 1, n, r, dp[l][r], 0, l);
  132.             updateTree (1, 1, n, l, dp[l][r], 1, r);
  133.            
  134.             //cout << l << ' ' << r << ' ' << dp[l][r] << "\n";
  135.         }
  136.     }
  137.    
  138.     int res = -INF;
  139.     for (int l = 1; l <= n; l++) {
  140.         int c = 0;
  141.         for (int r = l; r <= n; r++) {
  142.             if (A[r] & 1)
  143.                 c++;
  144.                
  145.             if (((prefixSum[r] - prefixSum[l - 1]) & 1) && c == 1)
  146.                 res = max (res, dp[l][r]);
  147.         }
  148.     }
  149.    
  150.     if (res == -INF)
  151.         cout << -1 << "\n";
  152.     else cout << res << "\n";
  153.    
  154.     return 0;
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement