Skip to content

Sequence

Problem Statement


Full Solution

Step 1: Split the array

Divide into two halves:

  • = first elements
  • = last elements

We will enumerate all subsequences of and separately.


Step 2: Enumerate subsequences with states

For each subset of a half:

  • Compute its sum.
  • Track the number of consecutive negatives.
  • Track whether the subsequence started with negatives (important for merging).

Specifically, we maintain:

  • con_neg: the maximum run of consecutive negatives inside the subsequence.
  • first_neg: number of negatives before the first positive (so we know how many negatives "lead" the subsequence).

If con_neg , the subsequence is valid for its half.
We insert its sum into a container indexed by first_neg.


Step 3: Meet in the middle

Now, when enumerating subsets of , we again compute con_neg and how the sequence ends (trailing negatives).
To combine with a subset from , we must ensure that the run of negatives crossing the boundary does not exceed 3.

Thus:

  • If ends with negatives, we can only merge with subsets of that begin with negatives.

This check guarantees the global subsequence never contains 4 consecutive negatives.


Step 4: Minimization

For each valid sum from , we search in the precomputed sums of (stored in sets for fast lookup).
We want the smallest sum_a sum_b .
This is done with a lower bound query.


Step 5: Answer

  • If no valid pair was found, print Impossible.
  • Otherwise, print the minimum sum found.

Complexity


Subtasks

  • Subtask 1 (15 pts): Elements are only or . Can brute force all subsequences.
  • Subtask 2 (15 pts): . Exhaustive works.
  • Subtask 3 (30 pts): . Direct brute force over the array is feasible.

Implementation

cpp
#include <bits/stdc++.h>
using namespace std;
    
int main () {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n;
  long long s;
  cin >> n >> s;
  vector<int> a((n + 1) / 2), b(n / 2);
  for (int i = 0; i < (n + 1) / 2; ++i) {
    cin >> a[i];
  } 
  for (int i = 0; i < n / 2; ++i) {
    cin >> b[i];
  }
  swap(a, b);
  vector<set<long long>> meet(4);
  for (int mask = 0; mask < (1 << a.size()); ++mask) {
    int con_neg = 0, first_pos = 0, first_neg = 0, cur_neg = 0;
    long long sum = 0;
    for (int i = 0; i < a.size(); ++i) {
      if (mask >> i & 1) {
        sum += a[i];
        if (a[i] < 0) {
          if (!first_pos) {
            ++first_neg;
          }
          con_neg = max(con_neg, ++cur_neg);
        }
        else {
          first_pos = 1;
          con_neg = max(con_neg, cur_neg);
          cur_neg = 0;
        }
      }
    }
    if (con_neg <= 3) {
      meet[first_neg].insert(sum);
    }
  }
  long long ans = 9e18;
  for (int mask = 0; mask < (1 << b.size()); ++mask) {
    int con_neg = 0, cur_neg = 0;
    long long sum = 0;
    for (int i = 0; i < b.size(); ++i) {
      if (mask >> i & 1) {
        sum += b[i];
        if (b[i] < 0) {
          con_neg = max(con_neg, ++cur_neg);
        }
        else {
          con_neg = max(con_neg, cur_neg);
          cur_neg = 0;
        }
      }
    }
    if (con_neg <= 3) {
      for (int k = 0; k + cur_neg <= 3; ++k) {
        auto it = meet[k].lower_bound(s - sum);
        if (it != meet[k].end()) {
          ans = min(ans, sum + *it);
        }
      }
    }
  }
  if (ans == (long long)9e18) {
    cout << "Impossible";
  }
  else {
    cout << ans;
  }

  return 0;
}