Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <cassert>
- #include <ctime>
- #include <climits>
- #include <algorithm>
- #include <iostream>
- #include <fstream>
- #include <iomanip>
- #include <utility>
- #include <typeinfo>
- #include <memory>
- #include <iterator>
- #include <functional>
- #include <vector>
- #include <set>
- #include <deque>
- #include <queue>
- #include <stack>
- #include <map>
- #include <string>
- #include <bitset>
- #include <list>
- using namespace std;
- const int MAX_SIZE = 200500;
- const long long INF = (long long) 1e17;
- int n, k;
- int a [MAX_SIZE];
- int r [MAX_SIZE];
- long long ANS = -INF;
- int id1 = -1, id2 = -1;
- map < int, int > cnt;
- int cur;
- void add (int x) {
- if (++ cnt [x] == 1) {
- ++ cur;
- }
- }
- void del (int x) {
- if (-- cnt [x] == 0) {
- -- cur;
- }
- }
- int calc (int id) {
- while (id < n && cur < k) {
- add (a [id]);
- ++ id;
- }
- return (cur != k ? -1 : id - 1);
- }
- int lg;
- struct node {
- long long pref, suf, sum, maxsum;
- int r;
- node () {
- pref = -INF;
- suf = -INF;
- maxsum = -INF;
- sum = 0;
- r = -1;
- }
- bool operator == (node a) const {
- return (pref == a.pref && suf == a.suf && sum == a.sum && maxsum == a.maxsum);
- }
- } t [MAX_SIZE], empty;
- node merge (node l, node r) {
- node ans;
- if (l == empty && r == empty) {
- return empty;
- } else if (l == empty) {
- ans = r;
- } else if (r == empty) {
- ans = l;
- } else {
- if (l.pref > l.sum + r.pref) {
- ans.pref = l.pref;
- ans.r = l.r;
- } else {
- ans.pref = l.sum + r.pref;
- ans.r = r.r;
- }
- ans.suf = max (r.suf, r.sum + l.suf);
- ans.maxsum = max (l.suf + r.pref, max (l.maxsum, r.maxsum));
- ans.sum = l.sum + r.sum;
- }
- return ans;
- }
- void build (int v = 1, int tl = 0, int tr = lg - 1) {
- if (tl == tr) {
- t [v].sum = 1ll * a [tl];
- t [v].maxsum = max (t [v].maxsum, 1ll * a [tl]);
- t [v].pref = t [v].suf = t [v].maxsum;
- t [v].r = tl;
- } else {
- int tm = (tl + tr) >> 1;
- build (v << 1, tl, tm);
- build ((v << 1) | 1, tm + 1, tr);
- t [v] = merge (t [v << 1], t [(v << 1) | 1]);
- }
- }
- node get (int l, int r, int v = 1, int tl = 0, int tr = lg - 1) {
- if (l > r || tl > r || l > tr) {
- return empty;
- }
- if (l <= tl && tr <= r) {
- return t [v];
- }
- int tm = (tl + tr) >> 1;
- node f, s;
- f = get (l, r, v << 1, tl, tm);
- s = get (l, r, (v << 1) | 1, tm + 1, tr);
- return merge (f, s);
- }
- long long sum (int l, int r, int v = 1, int tl = 0, int tr = lg - 1) {
- if (l > r || tl > r || l > tr) {
- return 0;
- }
- if (l <= tl && tr <= r) {
- return t [v].sum;
- }
- int tm = (tl + tr) >> 1;
- return sum (l, r, v << 1, tl, tm) + sum (l, r, (v << 1) | 1, tm + 1, tr);
- }
- int mx (int l, int r) {
- return get (l, r).r;
- }
- inline void solve () {
- memset (r, -1, sizeof r);
- cin >> n;
- cin >> k;
- lg = 1;
- while (lg < n) {
- lg <<= 1;
- }
- for (int i = 0; i < n; ++ i) {
- cin >> a [i];
- }
- build ();
- r [0] = calc (0);
- if (r [0] == -1) {
- cout << "IMPOSSIBLE" << endl;
- return;
- }
- int id = mx (r [0] + 1, n - 1);
- long long tmp = sum (0, r [0]) + sum (r [0] + 1, id);
- if (ANS < tmp) {
- ANS = tmp;
- id1 = 0;
- id2 = (id == -1 ? r [0] : id);
- }
- del (a [0]);
- for (int i = 1; i < n; ++ i) {
- if (cur == k && r [i - 1] >= i) {
- r [i] = r [i - 1];
- } else {
- r [i] = calc (r [i - 1] + 1);
- }
- if (r [i] == -1) {
- break;
- }
- id = mx (r [i] + 1, n - 1);
- long long tmp = sum (i, r [i]) + sum (r [i] + 1, id);
- if (ANS < tmp) {
- ANS = tmp;
- id1 = i;
- id2 = (id == -1 ? r [i] : id);
- }
- del (a [i]);
- }
- if (ANS == -INF) {
- cout << "IMPOSSIBLE" << endl;
- } else {
- cout << ANS << endl;
- cout << id1 + 1 << " " << id2 + 1 << endl;
- }
- }
- int main () {
- assert (freopen ("threemax.in", "r", stdin));
- assert (freopen ("threemax.out", "w", stdout));
- solve ();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement