1+ /*
2+ DAY 4
3+ Q2 Accumulator Apex
4+ .*/
5+ /*
6+ We can only take elements from the left of each list, so every valid move is some prefix of a list.
7+
8+ For each prefix we know:
9+
10+ pref = sum of the prefix
11+
12+ mn = minimum prefix sum while walking through it
13+
14+ A prefix is usable only if:
15+
16+ x + mn >= 0
17+
18+
19+ If we take it, we end with:
20+
21+ x += pref
22+
23+
24+ We consider all prefixes from all lists and always pick the one that safely gives the most benefit.
25+ For each list we only keep the best prefix we have already used.
26+
27+ */
28+
29+ #include < bits/stdc++.h>
30+ using namespace std ;
31+
32+ struct Item {
33+ long long pref;
34+ long long minPref;
35+ int idx;
36+ };
37+
38+ struct Cmp {
39+ bool operator ()(const Item& a, const Item& b) const {
40+ if (a.minPref != b.minPref ) return a.minPref < b.minPref ;
41+ return a.pref < b.pref ;
42+ }
43+ };
44+
45+ int main () {
46+
47+
48+ long long x;
49+ int k;
50+ cin >> x >> k;
51+
52+ vector<vector<long long >> lists (k);
53+ for (int i = 0 ; i < k; ++i) {
54+ int len;
55+ cin >> len;
56+ lists[i].resize (len);
57+ for (int j = 0 ; j < len; ++j) cin >> lists[i][j];
58+ }
59+
60+ priority_queue<Item, vector<Item>, Cmp> pq;
61+ vector<vector<long long >> pref (k);
62+
63+ for (int i = 0 ; i < k; ++i) {
64+ long long s = 0 , mn = 0 ;
65+ pref[i].push_back (0 );
66+ for (auto v : lists[i]) {
67+ s += v;
68+ mn = min (mn, s);
69+ pref[i].push_back (s);
70+ pq.push ({s, mn, i});
71+ }
72+ }
73+
74+ long long best = x;
75+ vector<long long > taken (k, 0 );
76+
77+ while (!pq.empty ()) {
78+ auto cur = pq.top ();
79+ pq.pop ();
80+
81+ if (best + cur.minPref < 0 ) break ;
82+
83+ if (cur.pref > taken[cur.idx ]) {
84+ best -= taken[cur.idx ];
85+ best += cur.pref ;
86+ taken[cur.idx ] = cur.pref ;
87+ }
88+ }
89+
90+ cout << best << " \n " ;
91+ return 0 ;
92+ }
93+
94+
95+
96+
97+ // TC =O(Nlog(N)) and SC = O(N)
98+ /*
99+ My submission : https://codeforces.com/contest/1912/submission/355690272
100+ */
0 commit comments