Advertisement
tien_noob

Convex Hull Trick - N log N(Holy shiet)

Sep 29th, 2021
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.95 KB | None | 0 0
  1. //Make CSP great again
  2. //You're as beautiful as the day I lost you
  3. #include <bits/stdc++.h>
  4. #define TASK "BUILDING"
  5. using namespace std;
  6. ///Source : USACO Guilde - Advanced - LineContainer
  7. struct CHT
  8. {
  9.     struct Frac
  10.     {
  11.         long long u, v;
  12.         Frac(long long a, long long b)
  13.         {
  14.             u = a;
  15.             v = b;
  16.         }
  17.         bool operator < (const Frac other) const
  18.         {
  19.             long long a = u * other.v - v * other.u, b = v * other.v;
  20.             {
  21.                 if (a < 0 && b > 0 || a > 0 && b < 0)
  22.                 {
  23.                     return true;
  24.                 }
  25.                 return false;
  26.             }
  27.         }
  28.         bool operator <= (const Frac other) const
  29.         {
  30.             long long a = u * other.v - v * other.u, b = v * other.v;
  31.             {
  32.                 if (a < 0 && b > 0 || a > 0 && b < 0 || a == 0)
  33.                 {
  34.                     return true;
  35.                 }
  36.                 return false;
  37.             }
  38.         }
  39.     };
  40.     struct Line
  41.     {
  42.         bool type;
  43.         Frac x;
  44.         long long m, c;
  45.         bool operator < (const Line other) const
  46.         {
  47.             if (type || other.type)
  48.             {
  49.                 return x < other.x;
  50.             }
  51.             return m > other.m;
  52.         }
  53.     };
  54.     set<Line> cht;
  55.     Frac Intersect(set<Line>::iterator l1, set<Line>::iterator l2)
  56.     {
  57.         return Frac((l1->c - l2->c), (l2->m - l1->m));
  58.     }
  59.     bool has_prev(set<Line>::iterator it)
  60.     {
  61.         return it != cht.begin();
  62.     }
  63.     bool has_next(set<Line>::iterator it)
  64.     {
  65.         return it != cht.end() && next(it) != cht.end();
  66.     }
  67.     void Cal(set<Line>::iterator it)
  68.     {
  69.         if (has_prev(it))
  70.         {
  71.             Line ha = *it;
  72.             ha.x = Intersect(prev(it), it);
  73.             cht.insert(cht.erase(it), ha);
  74.         }
  75.     }
  76.     bool bad(set<Line>::iterator it)
  77.     {
  78.         if (has_next(it) && next(it)->c <= it->c)
  79.         {
  80.             return true;
  81.         }
  82.         return has_prev(it) && has_next(it) && Intersect(prev(it), next(it)) <= Intersect(prev(it), it);
  83.     }
  84.     void add_line(long long m, long long c)
  85.     {
  86.         set<Line>:: iterator it;
  87.         it = cht.lower_bound({0, Frac(0, 1), m, c});
  88.         if (it != cht.end() && it->m == m)
  89.         {
  90.             if (it->c <= c)
  91.             {
  92.                 return ;
  93.             }
  94.             cht.erase(it);
  95.         }
  96.         it = cht.insert({0, Frac(0, 1), m, c}).first;
  97.         if (bad(it))
  98.         {
  99.             cht.erase(it);
  100.         }
  101.         else
  102.         {
  103.             while (has_prev(it) && bad(prev(it)))
  104.             {
  105.                 cht.erase(prev(it));
  106.             }
  107.             while (has_next(it) && bad(next(it)))
  108.             {
  109.                 cht.erase(next(it));
  110.             }
  111.             if (has_next(it))
  112.             {
  113.                 Cal(next(it));
  114.             }
  115.             Cal(it);
  116.         }
  117.     }
  118.     long long Get(long long h)
  119.     {
  120.         Line l = *prev(cht.upper_bound({1, Frac(h, 1), 0, 0}));
  121.         return l.m * h + l.c;
  122.     }
  123. };
  124. CHT cht;
  125. const int N = 1e5;
  126. int w[N + 1], h[N + 1], n;
  127. long long dp[N + 1], s = 0;
  128. void read()
  129. {
  130.     cin >> n;
  131.     for (int i = 1; i <= n; ++ i)
  132.     {
  133.         cin >> h[i];
  134.     }
  135.     for (int i = 1; i <= n; ++ i)
  136.     {
  137.         cin >> w[i];
  138.         s += w[i];
  139.     }
  140. }
  141. void solve()
  142. {
  143.     dp[1] = -w[1];
  144.     for (int i = 2; i <= n; i++)
  145.     {
  146.         cht.add_line(-2 * h[i - 1], dp[i - 1] + h[i - 1] * h[i - 1]);
  147.         dp[i] = cht.Get(h[i]) - w[i] + h[i] * h[i];
  148.     }
  149.     cout << s + dp[n];
  150. }
  151. int main()
  152. {
  153.    ios_base::sync_with_stdio(false);
  154.    cin.tie(nullptr);
  155.    if (fopen(TASK".INP", "r"))
  156.    {
  157.       freopen(TASK".INP", "r", stdin);
  158.       freopen(TASK".OUT", "w", stdout);
  159.    }
  160.    int t = 1;
  161.    bool typetest = false;
  162.    if (typetest)
  163.    {
  164.       cin >> t;
  165.    }
  166.    for (int __ = 1; __ <= t; ++ __)
  167.    {
  168.       read();
  169.       solve();
  170.    }
  171. }
  172.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement