1+ #include < bits/stdc++.h>
2+
3+ using namespace std ;
4+ #define int long long
5+
6+ // time complexity: O(n*log(n))
7+ // space complexity: O(n)
8+ // submission link: https://codeforces.com/problemset/submission/1912/355861913
9+
10+ struct Segment {
11+ int cost; // min cost (-ve elements before +ve gain)
12+ int gain; // net gain
13+ int idx; // list idx
14+
15+ // priority Queue needs to order by cost
16+ // priority_queue is a max-heap, so we use > for min-heap behavior
17+ bool operator >(const Segment& other) const {
18+ return cost > other.cost ;
19+ }
20+ };
21+
22+ int solve (){
23+ int x, k; cin>>x>>k;
24+
25+ vector<vector<Segment>> segments (k);
26+
27+ for (int i = 0 ; i < k; i++){
28+ int t; cin >> t;
29+ int sum = 0 ;
30+ int cost = 0 ;
31+
32+ for (int j = 0 ; j < t; j++){
33+ int val; cin >> val;
34+ sum += val;
35+ cost = min (cost, sum);
36+
37+ // If we found a net positive chunk, save it as a segment
38+ if (sum > 0 ){
39+ // If cost is -5, we need at least 5. If cost is 2, we need 0.
40+ segments[i].push_back ({max (0LL , -cost), sum, i});
41+ sum = cost = 0 ;
42+ }
43+ }
44+ }
45+
46+ priority_queue<Segment, vector<Segment>, greater<Segment>> pq;
47+ vector<int > ptr (k, 0 ); // ptrs for each list's current idx
48+
49+ // add the first segment of each list (if it exists)
50+ for (int i = 0 ; i < k; i++){
51+ if (segments[i].size () > 0 ){
52+ pq.push (segments[i][0 ]);
53+ }
54+ }
55+
56+ while (!pq.empty ()){
57+ Segment best = pq.top ();
58+ pq.pop ();
59+
60+ if (x >= best.cost ){
61+ x += best.gain ;
62+ int i = best.idx ; // mov ptr forward
63+ ptr[i]++;
64+ if (ptr[i] < segments[i].size ()){
65+ pq.push (segments[i][ptr[i]]);
66+ }
67+ }
68+ else break ;
69+ }
70+
71+ return x;
72+ }
73+
74+ int32_t main ()
75+ {
76+ ios_base::sync_with_stdio (false );
77+ cin.tie (NULL );
78+
79+ cout << solve () << endl;
80+
81+ return 0 ;
82+ }
0 commit comments