Guest User

Untitled

a guest
Jan 10th, 2021
586
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.32 KB | None | 0 0
  1. #include <algorithm>
  2. #include <array>
  3. #include <assert.h>
  4. #include <bitset>
  5. #include <chrono>
  6. #include <cmath>
  7. #include <complex>
  8. #include <cstring>
  9. #include <functional>
  10. #include <fstream>
  11. #include <iomanip>
  12. #include <iostream>
  13. #include <istream>
  14.  
  15. #include <map>
  16. #include <math.h>
  17. #include <numeric>
  18. #include <ostream>
  19. #include <queue>
  20. #include <set>
  21. #include <stack>
  22. #include <string>
  23. #include <unordered_map>
  24. #include <unordered_set>
  25. #include <vector>
  26.  
  27. namespace asl
  28. {
  29.     typedef long long i64;
  30.    
  31. #include <stdint.h>
  32.  
  33.     template <typename A, typename B>
  34.     std::istream &operator>>(std::istream &is, std::pair<A, B> &p)
  35.     {
  36.         return is >> p.first >> p.second;
  37.     }
  38.  
  39.     template <typename T>
  40.     using vec = std::vector<T>;
  41.  
  42.     template <typename T>
  43.     std::istream &operator>>(std::istream &is, std::vector<T> &vec)
  44.     {
  45.         for (auto &value : vec)
  46.             is >> value;
  47.         return is;
  48.     }
  49.  
  50. }
  51.  
  52. #include <experimental/optional>
  53. #define optional std::experimental::optional
  54.  
  55. namespace asl
  56. {
  57.    
  58.     template <typename T, typename U = T>
  59.     class SegmentTree
  60.     {
  61.         int size;
  62.         std::function<void(T &, U &)> _update;
  63.         std::function<T(T &, T &)> _merge;
  64.         std::function<optional<U>(T &)> _get_lazy;
  65.  
  66.         void push(int p, int l, int r)
  67.         {
  68.             auto lazy = _get_lazy(ds[p]);
  69.  
  70.             if (lazy)
  71.             {
  72.                 _update(ds[l], *lazy);
  73.                 _update(ds[r], *lazy);
  74.             }
  75.         }
  76.  
  77.         void update(int p, int b, int e, int x, int y, U &upd)
  78.         {
  79.             if (x <= b && e <= y)
  80.             {
  81.                 _update(ds[p], upd);
  82.             }
  83.             else
  84.             {
  85.                 int m = (b + e) >> 1, l = p + 1, r = p + ((m - b) << 1);
  86.  
  87.                 push(p, l, r);
  88.  
  89.                 if (x < m)
  90.                     update(l, b, m, x, y, upd);
  91.  
  92.                 if (m < y)
  93.                     update(r, m, e, x, y, upd);
  94.  
  95.                 ds[p] = _merge(ds[l], ds[r]);
  96.             }
  97.         }
  98.  
  99.         T query(int p, int b, int e, int x, int y)
  100.         {
  101.             if (x <= b && e <= y)
  102.             {
  103.                 return ds[p];
  104.             }
  105.             else
  106.             {
  107.                 int m = (b + e) >> 1, l = p + 1, r = p + ((m - b) << 1);
  108.  
  109.                 push(p, l, r);
  110.  
  111.                 if (x < m)
  112.                 {
  113.                     auto le = query(l, b, m, x, y);
  114.  
  115.                     if (m < y)
  116.                     {
  117.                         auto ri = query(r, m, e, x, y);
  118.                         return _merge(le, ri);
  119.                     }
  120.                     else
  121.                     {
  122.                         return le;
  123.                     }
  124.                 }
  125.                 else
  126.                 {
  127.                     return query(r, m, e, x, y);
  128.                 }
  129.             }
  130.         }
  131.  
  132.         void init(int size,
  133.                   std::function<void(T &, U &)> update,
  134.                   std::function<T(T &, T &)> merge,
  135.                   std::function<optional<U>(T &)> get_lazy)
  136.         {
  137.             this->size = size;
  138.             this->_update = update;
  139.             this->_merge = merge;
  140.             this->_get_lazy = get_lazy;
  141.             this->ds = std::vector<T>(2 * size - 1);
  142.         }
  143.  
  144.     public:
  145.         std::vector<T> ds;
  146.  
  147.         SegmentTree(
  148.             int size,
  149.             std::function<void(T &, U &)> update,
  150.             std::function<T(T &, T &)> merge = [](T &l, T &r) { return l + r; },
  151.             std::function<optional<U>(T &)> get_lazy = [](T &value) { return optional<U>(); })
  152.         {
  153.             init(size, update, merge, get_lazy);
  154.         }
  155.  
  156.         void update(int x, U upd)
  157.         {
  158.             update(0, 0, size, x, x + 1, upd);
  159.         }
  160.  
  161.         T query(int x, int y)
  162.         {
  163.             return query(0, 0, size, x, y);
  164.         }
  165.     };
  166. }
  167.  
  168. #include <utility>
  169.  
  170. #include <tuple>
  171.  
  172. #include <random>
  173.  
  174. #define endl '\n'
  175.  
  176. using namespace std;
  177. using namespace asl;
  178.  
  179. const i64 inf = 8e9;
  180.  
  181. void my_update(i64 &a, i64 b) { a = b; }
  182.  
  183. i64 my_merge(i64 &a, i64 &b) { return min(a, b); }
  184.  
  185. i64 go(vec<pair<i64, i64>> &a)
  186. {
  187.     sort(a.begin(), a.end());
  188.  
  189.     int p = 0;
  190.     while (p < a.size() && a[p].first <= 0)
  191.         ++p;
  192.  
  193.     vec<SegmentTree<i64, i64>> sts(4, SegmentTree<i64, i64>(p, my_update, my_merge));
  194.  
  195.     vec<i64> his(p);
  196.     vec<i64> los(p);
  197.  
  198.     i64 hi = 0, lo = 0;
  199.  
  200.     for (int i = 0; i < p; ++i)
  201.     {
  202.         his[i] = hi;
  203.         los[i] = lo;
  204.  
  205.         i64 dist = -a[i].first;
  206.         assert(dist >= 0);
  207.  
  208.         for (int m = 0; m < 4; ++m)
  209.         {
  210.             i64 cur = dist + (m & 2) * hi + (m & 1) * lo;
  211.             sts[m].update(i, cur);
  212.         }
  213.  
  214.         hi = max(hi, a[i].second);
  215.         lo = max(lo, -a[i].second);
  216.     }
  217.  
  218.     i64 solution = inf;
  219.  
  220.     auto check_interval = [&](int b, int e, i64 delta, int index) {
  221.         if (b < e)
  222.             solution = min(solution, sts[index].query(b, e) + delta);
  223.     };
  224.  
  225.     hi = 0, lo = 0;
  226.  
  227.     for (int i = a.size() - 1; i >= 0 && a[i].first >= 0; --i)
  228.     {
  229.         i64 dist = 2 * a[i].first;
  230.  
  231.         int hi_pos = lower_bound(his.begin(), his.end(), hi) - his.begin();
  232.         int lo_pos = lower_bound(los.begin(), los.end(), lo) - los.begin();
  233.  
  234.         check_interval(0, min(lo_pos, hi_pos), 2 * hi + lo + dist, 0);
  235.         check_interval(lo_pos, hi_pos, 2 * hi + dist, 1);
  236.         check_interval(hi_pos, lo_pos, lo + dist, 2);
  237.         check_interval(max(lo_pos, hi_pos), p, dist, 3);
  238.  
  239.         hi = max(hi, a[i].second);
  240.         lo = max(lo, -a[i].second);
  241.     }
  242.  
  243.     return solution;
  244. }
  245.  
  246. void solve()
  247. {
  248.     int n;
  249.     cin >> n;
  250.  
  251.     vec<pair<i64, i64>> a(n);
  252.     cin >> a;
  253.  
  254.     i64 big = 1e9 + 1;
  255.     a.push_back({0, 0});
  256.    
  257.     i64 solution = inf;
  258.  
  259.     for (int x = 0; x < 2; ++x)
  260.     {
  261.         for (int y = 0; y < 2; ++y)
  262.         {
  263.             solution = min(solution, go(a));
  264.  
  265.             for (auto &p : a)
  266.                 p.second *= -1;
  267.         }
  268.  
  269.         for (auto &p : a)
  270.             p.first *= -1;
  271.     }
  272.  
  273.     cout << solution << endl;
  274. }
  275.  
  276. int main()
  277. {
  278.     ios_base::sync_with_stdio(0);
  279.     cin.tie(0);
  280.  
  281.     int t;
  282.     cin >> t;
  283.  
  284.     for (int i = 1; i <= t; ++i)
  285.     {
  286.         solve();
  287.        
  288.     }
  289.  
  290.     return 0;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment