Advertisement
Guest User

Untitled

a guest
Sep 8th, 2019
613
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.41 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef pair<double,double> ll;
  4. int n,k; ///n is arr size, k is number of groups to split arr into
  5. long long arr[20005]; ///our original array
  6. long long pre[20005];
  7. double val;
  8. long long groups; ///for returning value once convex_hull() is called
  9. struct linear_hull{
  10.     deque<ll> dq;
  11.     deque<long long> cuts;
  12.     double intercept (ll i, ll j){
  13.         return ((double)(j.second-i.second))/((double)(i.first-j.first));
  14.     }
  15.     void remove(double i){
  16.         ll _front=dq.front();
  17.         dq.pop_front();
  18.         while (!dq.empty() && intercept(_front,dq.front())<=i){
  19.             _front=dq.front();
  20.             dq.pop_front();
  21.             cuts.pop_front();
  22.         }
  23.         dq.push_front(_front);
  24.     }
  25.     void add(ll i,long long j){
  26.         if (!dq.empty()){
  27.             ll _back=dq.back();
  28.             dq.pop_back();
  29.             while (!dq.empty() && intercept(i,dq.back())<= intercept(_back,dq.back())){
  30.                 _back=dq.back();
  31.                 dq.pop_back();
  32.                 cuts.pop_back();
  33.             }
  34.             dq.push_back(_back);
  35.         }
  36.         dq.push_back(i);
  37.         cuts.push_back(j);
  38.     }
  39.     void init(){
  40.         dq.clear();
  41.         cuts.clear();
  42.     }
  43.     double get(long long x){
  44.         this->remove(x);
  45.         return dq.front().first*x+dq.front().second;
  46.     }
  47.     long long getcuts(){
  48.         return cuts.front();
  49.     }
  50. } *hull=new linear_hull();
  51. //so we know how many cuts is used when doing our linear convex hull
  52.  
  53. void lagrangian_multiplier(double cost){
  54.     hull->init();
  55.     hull->add(ll(0,0),0);
  56.     double best;
  57.     for (long long x=1;x<n;x++){
  58.         best=hull->get(pre[x])+pre[x]*pre[x];
  59.         hull->add(ll(-2*pre[x],best+pre[x]*pre[x]+cost),(hull->getcuts())+1);
  60.     }
  61.     val=hull->get(pre[n])+pre[n]*pre[n];
  62.     groups=hull->getcuts() + 1;
  63. }
  64.  
  65. int main(){
  66.     scanf("%d%d",&n,&k);
  67.     for (int x=1;x<=n;x++) scanf("%d",&arr[x]);
  68.     for (int x=1;x<=n;x++) pre[x]=arr[x]+pre[x-1];
  69.     double a = 0, b = 2e9, c = -1;
  70.     for (int it = 0; it < 400; ++it) {
  71.       c = 0.5 * (a + b);
  72.       lagrangian_multiplier(c);
  73.       if (groups > k) {
  74.         a = c;
  75.       } else {
  76.         b = c;
  77.       }
  78.     }
  79.     lagrangian_multiplier((a + b) * 0.5);
  80.     cout << (long long)round(val - (k - 1) * (a + b) * 0.5) << endl;  ///rmb to minus the extra cost in lagrange speedup to get the actual value
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement