Advertisement
Guest User

Sequence Partition

a guest
Jul 31st, 2013
640
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.76 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <map>
  4. #include <set>
  5.  
  6. #define INF 500000000
  7. #define MAX_N 15100
  8. #define RIGHT 32768
  9. #define SIZE 65537
  10.  
  11. using namespace std;
  12.  
  13. int N, K, T;
  14. int A[MAX_N], S[MAX_N];
  15. map<int,int> Idx; // Contains index in Tree of prefix sum
  16.  
  17. // Tree class
  18. // first contains min partitions so that each partition sum is <= M
  19. // second contains max partitions that can be made so that each partition sum is <= M
  20.  
  21. class T
  22. {
  23. private:
  24.     pair<int,int> node[SIZE];
  25. public:
  26.     pair<int,int> query(int r, int n, int a, int b);
  27.     void reset();
  28.     void update(int i, pair<int,int> p, int n, int a, int b);
  29. } Tree;
  30.  
  31. void T::reset()
  32. {
  33.     for(int i = 0; i < SIZE; i++)
  34.         node[i].first = INF, node[i].second = -INF;
  35.  
  36.     update(Idx[0], make_pair(0,0), 1, 1, RIGHT);
  37. }
  38.  
  39. void T::update(int i, pair<int,int> p, int n, int a, int b)
  40. {
  41.     if(i < a || i > b)
  42.         return;
  43.     if(i == a && i == b)
  44.     {
  45.         node[n] = p;
  46.         return;
  47.     }
  48.  
  49.     int mid = (a+b) / 2;
  50.     update(i, p, 2*n, a, mid);
  51.     update(i, p, 2*n + 1, mid + 1, b);
  52.     node[n].first = min(node[2*n].first, node[2*n + 1].first);
  53.     node[n].second = max(node[2*n].second, node[2*n + 1].second);
  54. }
  55.  
  56. pair<int,int> T::query(int r, int n, int a, int b)
  57. {
  58.     if(b < r)
  59.         return make_pair(INF, -INF);
  60.     if(a >= r)
  61.         return node[n];
  62.  
  63.     int mid = (a+b) / 2;
  64.     pair<int,int> p = query(r, 2*n, a, mid);
  65.     pair<int,int> q = query(r, 2*n + 1, mid + 1, b);
  66.     return make_pair(min(p.first, q.first), max(p.second, q.second));
  67. }
  68.  
  69. bool possible(int m)
  70. {
  71.     // Compress prefix sums
  72.  
  73.     set<int> s;
  74.     for(int i = 0; i <= N; i++)
  75.         s.insert(S[i]), s.insert(S[i] - m);
  76.  
  77.     Idx.clear();
  78.     int i = 1;
  79.     for(set<int>::iterator it = s.begin(); it != s.end(); it++, i++)
  80.         Idx[*it] = i;
  81.  
  82.     // Find answer with DP
  83.  
  84.     Tree.reset();
  85.  
  86.     for(int i = 1; i <= N; i++)
  87.     {
  88.         pair<int,int> p = Tree.query(Idx[S[i] - m], 1, 1, RIGHT);
  89.         p.first++, p.second++;
  90.         Tree.update(Idx[S[i]], p, 1, 1, RIGHT);
  91.     }
  92.  
  93.     pair<int,int> p = Tree.query(Idx[S[N]], 1, 1, RIGHT);
  94.     return p.first <= K && p.second >= K;
  95. }
  96.  
  97. int minM()
  98. {
  99.     // Binary search on M
  100.  
  101.     int a = -INF, b = INF;
  102.     int p = (a+b) / 2;
  103.  
  104.     while(b > a+1)
  105.     {
  106.         if(possible(p))
  107.             b = p;
  108.         else
  109.             a = p;
  110.  
  111.         p = (a+b) / 2;
  112.     }
  113.  
  114.     if(possible(a))
  115.         return a;
  116.     else
  117.         return b;
  118. }
  119.  
  120. int main()
  121. {
  122.     cin >> T;
  123.  
  124.     while(T--)
  125.     {
  126.         cin >> N >> K;
  127.         int s = 0;
  128.  
  129.         for(int i = 1; i <= N; i++)
  130.         {
  131.             cin >> A[i];
  132.             S[i] = S[i-1] + A[i];
  133.         }
  134.  
  135.         cout << minM() << "\n";
  136.     }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement