Advertisement
Guest User

I

a guest
Nov 27th, 2014
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.40 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <cassert>
  6. #include <ctime>
  7. #include <climits>
  8.  
  9. #include <algorithm>
  10. #include <iostream>
  11. #include <fstream>
  12. #include <iomanip>
  13. #include <utility>
  14. #include <typeinfo>
  15. #include <memory>
  16. #include <iterator>
  17. #include <functional>
  18.  
  19. #include <vector>
  20. #include <set>
  21. #include <deque>
  22. #include <queue>
  23. #include <stack>
  24. #include <map>
  25. #include <string>
  26. #include <bitset>
  27. #include <list>
  28.  
  29. using namespace std;
  30.  
  31. const int MAX_SIZE = 200500;
  32. const long long INF = (long long) 1e17;
  33.  
  34. int n, k;
  35. int a [MAX_SIZE];
  36. int r [MAX_SIZE];
  37. long long ANS = -INF;
  38. int id1 = -1, id2 = -1;
  39.  
  40. map < int, int > cnt;
  41. int cur;
  42.  
  43. void add (int x) {
  44.     if (++ cnt [x] == 1) {
  45.         ++ cur;
  46.     }
  47. }
  48.  
  49. void del (int x) {
  50.     if (-- cnt [x] == 0) {
  51.         -- cur;
  52.     }
  53. }
  54.  
  55. int calc (int id) {
  56.     while (id < n && cur < k) {
  57.         add (a [id]);
  58.         ++ id;
  59.     }
  60.     return (cur != k ? -1 : id - 1);
  61. }
  62.  
  63. int lg;
  64. struct node {
  65.     long long pref, suf, sum, maxsum;
  66.     int r;
  67.     node () {
  68.         pref = -INF;
  69.         suf = -INF;
  70.         maxsum = -INF;
  71.         sum = 0;
  72.         r = -1;
  73.     }
  74.     bool operator == (node a) const {
  75.         return (pref == a.pref && suf == a.suf && sum == a.sum && maxsum == a.maxsum);
  76.     }
  77. } t [MAX_SIZE], empty;
  78.  
  79. node merge (node l, node r) {
  80.     node ans;
  81.     if (l == empty && r == empty) {
  82.         return empty;
  83.     } else if (l == empty) {
  84.         ans = r;
  85.     } else if (r == empty) {
  86.         ans = l;
  87.     } else {
  88.         if (l.pref > l.sum + r.pref) {
  89.             ans.pref = l.pref;
  90.             ans.r = l.r;
  91.         } else {
  92.             ans.pref = l.sum + r.pref;
  93.             ans.r = r.r;
  94.         }
  95.         ans.suf = max (r.suf, r.sum + l.suf);
  96.         ans.maxsum = max (l.suf + r.pref, max (l.maxsum, r.maxsum));
  97.         ans.sum = l.sum + r.sum;
  98.     }
  99.    
  100.     return ans;
  101. }
  102.  
  103. void build (int v = 1, int tl = 0, int tr = lg - 1) {
  104.     if (tl == tr) {
  105.         t [v].sum = 1ll * a [tl];
  106.         t [v].maxsum = max (t [v].maxsum, 1ll * a [tl]);
  107.         t [v].pref = t [v].suf = t [v].maxsum;
  108.         t [v].r = tl;
  109.     } else {
  110.         int tm = (tl + tr) >> 1;
  111.         build (v << 1, tl, tm);
  112.         build ((v << 1) | 1, tm + 1, tr);
  113.         t [v] = merge (t [v << 1], t [(v << 1) | 1]);
  114.     }
  115. }
  116.  
  117. node get (int l, int r, int v = 1, int tl = 0, int tr = lg - 1) {
  118.     if (l > r || tl > r || l > tr) {
  119.         return empty;
  120.     }
  121.     if (l <= tl && tr <= r) {
  122.         return t [v];
  123.     }
  124.     int tm = (tl + tr) >> 1;
  125.     node f, s;
  126.     f = get (l, r, v << 1, tl, tm);
  127.     s = get (l, r, (v << 1) | 1, tm + 1, tr);
  128.     return merge (f, s);
  129. }
  130.  
  131. long long sum (int l, int r, int v = 1, int tl = 0, int tr = lg - 1) {
  132.     if (l > r || tl > r || l > tr) {
  133.         return 0;
  134.     }
  135.     if (l <= tl && tr <= r) {
  136.         return t [v].sum;
  137.     }
  138.     int tm = (tl + tr) >> 1;
  139.     return sum (l, r, v << 1, tl, tm) + sum (l, r, (v << 1) | 1, tm + 1, tr);
  140. }
  141.  
  142. int mx (int l, int r) {
  143.     return get (l, r).r;
  144. }
  145.  
  146. inline void solve () {
  147.     memset (r, -1, sizeof r);
  148.     cin >> n;
  149.     cin >> k;
  150.     lg = 1;
  151.     while (lg < n) {
  152.         lg <<= 1;
  153.     }
  154.     for (int i = 0; i < n; ++ i) {
  155.         cin >> a [i];
  156.     }
  157.     build ();
  158.     r [0] = calc (0);
  159.     if (r [0] == -1) {
  160.         cout << "IMPOSSIBLE" << endl;
  161.         return;
  162.     }
  163.     int id = mx (r [0] + 1, n - 1);
  164.     long long tmp = sum (0, r [0]) + sum (r [0] + 1, id);
  165.     if (ANS < tmp) {
  166.         ANS = tmp;
  167.         id1 = 0;
  168.         id2 = (id == -1 ? r [0] : id);
  169.     }
  170.     del (a [0]);
  171.     for (int i = 1; i < n; ++ i) {
  172.         if (cur == k && r [i - 1] >= i) {
  173.             r [i] = r [i - 1];
  174.         } else {
  175.             r [i] = calc (r [i - 1] + 1);
  176.         }
  177.         if (r [i] == -1) {
  178.             break;
  179.         }
  180.         id = mx (r [i] + 1, n - 1);
  181.         long long tmp = sum (i, r [i]) + sum (r [i] + 1, id);
  182.         if (ANS < tmp) {
  183.             ANS = tmp;
  184.             id1 = i;
  185.             id2 = (id == -1 ? r [i] : id);
  186.         }
  187.         del (a [i]);
  188.     }
  189.     if (ANS == -INF) {
  190.         cout << "IMPOSSIBLE" << endl;
  191.     } else {
  192.         cout << ANS << endl;
  193.         cout << id1 + 1 << " " << id2 + 1 << endl;
  194.     }
  195. }
  196.  
  197. int main () {
  198.     assert (freopen ("threemax.in", "r", stdin));
  199.     assert (freopen ("threemax.out", "w", stdout));
  200.     solve ();
  201.     return 0;
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement