Guest User

Modifies code with doubles

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