Submission #1173404

#TimeUsernameProblemLanguageResultExecution timeMemory
1173404hamzabcFeast (NOI19_feast)C++20
0 / 100
98 ms27864 KiB
#include <bits/stdc++.h> using namespace std; #define all(x) x.begin(), x.end() #define mod 1000000007 #define sp << " " << #define endl << '\n' vector<long long> feast; class divandqonqtree{ private: divandqonqtree *lfttree, *rgttree; struct prefixdata{ long long int maximumrightmostsum = 0; int leftind = 0; long long int maximumsubarraysum = 0; int kanadeleft = 0; int kanaderight = 0; }; struct sufixdata{ long long int maximumleftmostsum = 0; int rightind = 0; long long int maximumsubarraysum = 0; int kanadeleft = 0; int kanaderight = 0; }; vector<prefixdata> prefix; vector<sufixdata> sufix; int l, m, r; long long deg; public: void init(int gl, int gr){ l = gl; r = gr; m = (l + r) >> 1; if (gl == gr){ deg = feast[l]; return; } if (l < m){ lfttree = new divandqonqtree; lfttree->init(l, m - 1); } if (m < r){ rgttree = new divandqonqtree; rgttree->init(m + 1, r); } long long int sum = 0, kanade = 0, kl = m; prefix.resize(m - l + 1); sufix.resize(r - m + 1); for (int i = m; i <= r; i++){ sum += feast[i]; kanade += feast[i]; if (kanade < 0){ kanade = 0; kl = i + 1; } if (i == m){ sufix[0].maximumleftmostsum = max(0LL, sum); sufix[0].maximumsubarraysum = kanade; continue; } if (sufix[i - m - 1].maximumleftmostsum > sum){ sufix[i - m].maximumleftmostsum = sufix[i - m - 1].maximumleftmostsum; sufix[i - m].rightind = sufix[i - m - 1].rightind; }else{ sufix[i - m].maximumleftmostsum = sum; sufix[i - m].rightind = i; } if (sufix[i - m - 1].maximumsubarraysum > kanade){ sufix[i - m].maximumsubarraysum = sufix[i - m - 1].maximumsubarraysum; sufix[i - m].kanadeleft = sufix[i - m - 1].kanadeleft; sufix[i - m].kanaderight = sufix[i - m - 1].kanaderight; }else{ sufix[i - m].maximumsubarraysum = kanade; sufix[i - m].kanadeleft = kl; sufix[i - m].kanaderight = i; } } kl = m; sum = 0; kanade = 0; for (int i = m; i >= l; i--){ if (i == m){ prefix[0].maximumrightmostsum = sum; prefix[0].maximumsubarraysum = kanade; continue; } sum += feast[i]; kanade += feast[i]; if (kanade < 0){ kanade = 0; kl = i - 1; } if (prefix[m - i - 1].maximumrightmostsum > sum){ prefix[m - i].maximumrightmostsum = prefix[m - i - 1].maximumrightmostsum; prefix[m - i].leftind = prefix[m - i - 1].leftind; }else{ prefix[m - i].maximumrightmostsum = sum; prefix[m - i].leftind = i; } if (prefix[m - i - 1].maximumsubarraysum > kanade){ prefix[m - i].maximumsubarraysum = prefix[m - i - 1].maximumsubarraysum; prefix[m - i].kanadeleft = prefix[m - i - 1].kanadeleft; prefix[m - i].kanaderight = prefix[m - i - 1].kanaderight; }else{ prefix[m - i].maximumsubarraysum = kanade; prefix[m - i].kanadeleft = i; prefix[m - i].kanaderight = kl; } } }; array<long long, 3> query(int ql, int qr){ if (ql > qr) return { -1, -1, -1 }; if (qr < m){ return lfttree->query(ql, qr); } if (ql > m){ return rgttree->query(ql, qr); } if (l == r){ return { deg, l, r }; } long long mx = max(max(prefix[m - ql].maximumsubarraysum, sufix[qr - m].maximumsubarraysum), prefix[m - ql].maximumrightmostsum + sufix[qr - m].maximumleftmostsum); if (mx == prefix[m - ql].maximumsubarraysum) return { mx, prefix[m - ql].kanadeleft, prefix[m - ql].kanaderight }; if (mx == sufix[qr - m].maximumsubarraysum) return { mx, sufix[qr - m].kanadeleft, sufix[qr - m].kanaderight }; // if (mx == prefix[m - ql].maximumrightmostsum + sufix[qr - m].maximumleftmostsum) return { mx, prefix[m - ql].leftind, sufix[qr - m].rightind}; } }; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int N, K; cin >> N >> K; vector<long long> original(N); multiset<long long> sm; for (int i = 0; i < N; i++){ cin >> original[i]; sm.insert(-original[i]); } long long int sum = 0; for (int o = 0; o < K; o++){ if (*sm.begin() < 0) sum += -*sm.begin(); sm.erase(sm.begin()); } if (*sm.begin() >= 0){ cout << sum; return 0; } for (int i = 0; i < N; i++){ long long a = original[i]; if (a == 0) continue; if (feast.size() == 0 && a > 0){ feast.push_back(a); continue; } if (feast.back() * a > 0) feast.back() += a; else feast.push_back(a); } if (feast[feast.size() - 1] < 0) feast.pop_back(); divandqonqtree normal, inverse; normal.init(0, feast.size() - 1); for (int i = 0; i < feast.size(); i++) feast[i] *= -1; inverse.init(0, feast.size() - 1); priority_queue<array<long long, 6>> prt; auto u = normal.query(0, feast.size() - 1); prt.push({ u[0], 0LL, (long long)feast.size() - 1LL, (long long)true, u[1], u[2] }); long long int ret = 0; for (int i = 0; i < K; i++){ auto fr = prt.top(); prt.pop(); ret += fr[0]; if (fr[3]){ u = normal.query(fr[1], fr[4] - 1); prt.push({ u[0], fr[0], fr[4] - 1, true, u[1], u[2] }); u = normal.query(fr[5] + 1, fr[2]); prt.push({ u[0], fr[5] + 1, fr[1], true, u[1], u[2] }); u = inverse.query(fr[4], fr[5]); prt.push({ u[0], fr[4], fr[5], false, u[1], u[2] }); }else{ u = inverse.query(fr[1], fr[4] - 1); prt.push({ u[0], fr[0], fr[4] - 1, false, u[1], u[2] }); u = inverse.query(fr[5] + 1, fr[2]); prt.push({ u[0], fr[5] + 1, fr[1], false, u[1], u[2] }); u = normal.query(fr[4], fr[5]); prt.push({ u[0], fr[4], fr[5], true, u[1], u[2] }); } } cout << ret; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...