cppAcademy
FROM LEARNING TO COMPETING

Intermediate.
Put your skills to the test.

Bulgarian Informatics Group D · 2007–2026

270 independently explained problems: 54 Municipal, 54 Regional, 105 National Olympiad and 57 Autumn Tournament tasks. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group D also includes challenging national-level problems. The six 2017 National tasks shared by Groups C and D use their existing permanent URLs. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP D2022 · HardBitset dynamic programming

Longest Gap in Nonempty Subset Sums

National Olympiad — National round (2022 season)

Submission name: nosum.cpp

Problem summary

Find the longest run in[k1,k2] not representable by a nonempty subset sum of the signed input values.

Input

n k1 k2 and n values.

Output

The longest unrepresentable run length.

Constraints

1<n<500; −30000<k1<k2<30000; −1000≤a[i]≤1000.

Worked example

Input and output for the worked example discussed below.

Input

5 -7 11
4 -2 3 -5 6

Output

1

Solution analysis

  1. All subset sums fit within±499000. Use a bitset indexed by sum+500000, initially all clear because only nonempty subsets count.
  2. For each x, retain old sums and add their shifted copy by x, then mark singleton x. Positive x shifts left, negative x shifts right. The shifted expression uses the old state, preventing reuse of x.
  3. Scan the requested interval for the longest clear-bit run. The sample maximum is1. Zero becomes representable only if a nonempty subset genuinely sums to zero, not through an empty-subset initialization.

Why it works

Every nonempty subset omits the new value, is its singleton, or extends a previous nonempty subset. The update covers exactly these cases, proving the bitset by induction.

Complexity: O(nS/w+S+K) time and O(S) bits, S=1000001, K=k2−k1+1, with machine-word width w.

Watch out. Do not initialize an empty zero sum. Signed sums need the offset and opposite shift directions.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<set>
#include<bitset>
#include<algorithm>
using namespace std;
// Every nonempty subset omits the new value, is its singleton, or extends a previous nonempty subset.
int main(){
    const int offset=500000;
    int n,left,right;
    cin>>n>>left>>right;
    bitset<1000001>reachable;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        if(x>=0){
            reachable|=reachable<<x;
        }
        else{
            reachable|=reachable>>(-x);
        }
        reachable.set(offset+x);
    }
    int current=0,answer=0;
    for(int x=left;x<=right;x++){
        if(reachable[offset+x]){
            current=0;
        }
        else{
            current++;
            answer=max(answer,current);
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗