Saturday, November 9, 2019

[CS Academy] Squared Ends

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Squared Ends
Source            : Codeforces
Category          : Data Structure
Algorithm         : Dynamic Convex Hull Trick
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll              long long int  
  6.   
  7. static const int maxn = 2e5 + 5;  
  8.   
  9. // Dynamic Convex Hull Trick  
  10. // Keeps upper hull for maximums.  
  11. // add lines with -m and -b and return -ans to get minimums  
  12. // source : https://codeforces.com/blog/entry/11155?#comment-162462  
  13.   
  14. static const ll is_query = LLONG_MIN;  
  15.   
  16. struct Line  
  17. {  
  18.       ll m, b;  
  19.       mutable function <const Line*()> succ;  
  20.       bool operator < (const Line &rhs) const  
  21.       {  
  22.             if (rhs.b != is_query) return m < rhs.m;  
  23.             const Line *s = succ();  
  24.             if (!s) return 0;  
  25.             ll x = rhs.m;  
  26.             return (b - s->b) < ((s->m - m) * x);  
  27.       }  
  28. };  
  29.   
  30. struct CHT : public multiset <Line>  
  31. {  
  32.       bool bad(iterator y)  
  33.       {  
  34.             auto z = next(y);  
  35.             if (y == begin())  
  36.             {  
  37.                   if (z == end()) return 0;  
  38.                   return y->m == z->m && y->b <= z->b;  
  39.             }  
  40.             auto x = prev(y);  
  41.             if (z == end()) return y->m == x->m && y->b <= x->b;  
  42.             return 1.0 * (x->b - y->b) * (z->m - y->m) >= 1.0 * (y->b - z->b) * (y->m - x->m);  
  43.       }  
  44.       void add(ll m, ll b)  
  45.       {  
  46.             auto y = insert({m, b});  
  47.             y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };  
  48.             if (bad(y)) { erase(y); return; }  
  49.             while (next(y) != end() && bad(next(y))) erase(next(y));  
  50.             while (y != begin() && bad(prev(y))) erase(prev(y));  
  51.       }  
  52.       ll query(ll x)  
  53.       {  
  54.             auto l = *lower_bound((Line){x, is_query});  
  55.             return l.m * x + l.b;  
  56.       }  
  57. };  
  58.   
  59. ll sq(ll x)  
  60. {  
  61.       return x * x;  
  62. }  
  63.   
  64. ll dp[105][10005];  
  65.   
  66. signed main()  
  67. {  
  68.       ios_base::sync_with_stdio(false);  
  69.       cin.tie(nullptr);  
  70.       cout.tie(nullptr);  
  71.   
  72.       #ifndef ONLINE_JUDGE  
  73.             freopen("in.txt""r", stdin);  
  74.       #endif // ONLINE_JUDGE  
  75.   
  76.       int N, K;  
  77.       cin >> N >> K;  
  78.       vector <ll> arr(N + 1);  
  79.       for (int i = 1; i <= N; i++) cin >> arr[i];  
  80.       for (int i = 1; i <= N; i++) dp[1][i] = sq(arr[i] - arr[1]);  
  81.       for (int k = 2; k <= K; k++)  
  82.       {  
  83.             CHT cht;  
  84.             for (int i = k; i <= N; i++)  
  85.             {  
  86.                   cht.add(1LL * 2 * arr[i], -(1LL * sq(arr[i]) + dp[k - 1][i - 1]));  
  87.                   ll best = -(cht).query(arr[i]) + sq(arr[i]);  
  88.                   dp[k][i] = best;  
  89.             }  
  90.       }  
  91.       cout << dp[K][N] << endl;  
  92. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.