Submission #1299731

#TimeUsernameProblemLanguageResultExecution timeMemory
1299731chaitanyamehtaLasers (NOI19_lasers)C++20
100 / 100
109 ms11660 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    ll L;
    int R;
    if (!(cin >> L >> R)) return 0;

    vector<pair<ll,ll>> global_unavoidable;
    global_unavoidable.reserve(1000);

    for (int ri = 0; ri < R; ++ri) {
        int t; cin >> t;
        vector<ll> ps;
        ps.reserve(t + 1);
        ps.push_back(0);
        for (int j = 0; j < t; ++j) {
            ll w; cin >> w;
            ps.push_back(ps.back() + w);
        }
        ll S = ps.back();
        if (S == L) {
            // This row forces all lasers
            cout << L << '\n';
            return 0;
        }
        ll F = L - S;
        if (F <= 0) {
            // no free space (S >= L handled above), but guard
            global_unavoidable.emplace_back(1, L);
            continue;
        }

        // Build avoidable intervals [x+1, x+F] for each prefix x in ps
        vector<pair<ll,ll>> avoid;
        avoid.reserve(ps.size());
        for (ll x : ps) {
            ll l = x + 1;
            ll r = x + F;
            if (l > L || r < 1) continue;
            if (l < 1) l = 1;
            if (r > L) r = L;
            if (l <= r) avoid.emplace_back(l, r);
        }

        if (avoid.empty()) {
            // Nothing avoidable -> whole [1..L] unavoidable
            global_unavoidable.emplace_back(1, L);
            continue;
        }

        // Merge avoidable intervals (they are in increasing left order because ps is increasing)
        vector<pair<ll,ll>> merged_avoid;
        merged_avoid.reserve(avoid.size());
        for (size_t i = 0; i < avoid.size(); ++i) {
            ll l = avoid[i].first;
            ll r = avoid[i].second;
            if (merged_avoid.empty() || merged_avoid.back().second + 1 < l) {
                merged_avoid.emplace_back(l, r);
            } else {
                if (r > merged_avoid.back().second)
                    merged_avoid.back().second = r;
            }
        }

        // Complement of merged_avoid inside [1..L] -> unavoidable intervals for this row
        ll cur = 1;
        for (size_t i = 0; i < merged_avoid.size(); ++i) {
            ll l = merged_avoid[i].first;
            ll r = merged_avoid[i].second;
            if (cur < l) {
                global_unavoidable.emplace_back(cur, l - 1);
            }
            cur = r + 1;
            if (cur > L) break;
        }
        if (cur <= L) {
            global_unavoidable.emplace_back(cur, L);
        }
    }

    if (global_unavoidable.empty()) {
        cout << 0 << '\n';
        return 0;
    }

    // Merge global unavoidable intervals
    sort(global_unavoidable.begin(), global_unavoidable.end());
    ll ans = 0;
    pair<ll,ll> cur = global_unavoidable[0];
    for (size_t i = 1; i < global_unavoidable.size(); ++i) {
        pair<ll,ll> iv = global_unavoidable[i];
        if (cur.second + 1 < iv.first) {
            ans += (cur.second - cur.first + 1);
            cur = iv;
        } else {
            if (iv.second > cur.second) cur.second = iv.second;
        }
    }
    ans += (cur.second - cur.first + 1);
    if (ans > L) ans = L;
    cout << ans << '\n';
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...