Advertisement
Guest User

race time - convex hull trick

a guest
Jul 7th, 2015
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. double eps = 1e-7;
  4. typedef pair<int,int> pii;
  5. struct timeline
  6. {
  7.     int slope, intercept;
  8.     double stime, ftime;
  9.     timeline(int s, int i, double st, double ft)
  10.     {
  11.         slope = s;
  12.         intercept = i;
  13.         stime = st;
  14.         ftime = ft;
  15.     }
  16. };
  17. bool is_over(pii x, timeline y)
  18. {
  19.     double x1 = (x.first*y.stime)+x.second;
  20.     double x2 = (x.first*y.ftime)+x.second;
  21.  
  22.     double y1 = (y.slope*y.stime)+y.intercept;
  23.     double y2 = (y.slope*y.ftime)+y.intercept;
  24.  
  25.     if(x1 >= y1-eps && x2 >= y2-eps)
  26.         return true;
  27.     return false;
  28. }
  29. bool is_under(pii x, timeline y)
  30. {
  31.     double x1 = (x.first*y.stime)+x.second;
  32.     double x2 = (x.first*y.ftime)+x.second;
  33.  
  34.     double y1 = (y.slope*y.stime)+y.intercept;
  35.     double y2 = (y.slope*y.ftime)+y.intercept;
  36.  
  37.     if(x1 <= y1+eps && x2 <= y2+eps)
  38.         return true;
  39.     return false;
  40. }
  41. double find_intersection(pii x, timeline y)
  42. {
  43.     // cout<<x.first<<" "<<x.second<<" "<<y.slope<<" "<<y.intercept<<"\n";
  44.     if(x.first == y.slope)
  45.         return -100;
  46.     return ((y.intercept - x.second)*1.0)/((x.first - y.slope)*1.0);
  47. }
  48. vector <pii> A;
  49. int main()
  50. {
  51.     // freopen("input.txt", "r", stdin);
  52.     ios_base::sync_with_stdio(0);
  53.     int n, k;
  54.     scanf("%d %d", &n, &k);
  55.     A.resize(n);
  56.     for (int i = 0; i < n; ++i)
  57.     {
  58.         scanf("%d %d", &A[i].first, &A[i].second);
  59.     }
  60.     sort(A.rbegin(), A.rend());
  61.     vector <timeline> max_stack;
  62.     for (int i = 0; i < n; ++i)
  63.     {
  64.         double st = 0.0, ft = 0.0;
  65.         while(!max_stack.empty() && is_over(A[i], max_stack.back()))
  66.         {
  67.             ft = max_stack.back().ftime;
  68.             max_stack.pop_back();
  69.         }
  70.         if(max_stack.empty())
  71.         {
  72.             ft = k;
  73.             max_stack.push_back(timeline(A[i].first, A[i].second, st, ft));
  74.         }
  75.         else
  76.         {
  77.             ft = find_intersection(A[i], max_stack.back());
  78.             if(ft >= st+eps)
  79.             {
  80.                 timeline temp = max_stack.back();
  81.                 max_stack.pop_back();
  82.                 temp.stime = ft;
  83.                 max_stack.push_back(temp);
  84.                 max_stack.push_back(timeline(A[i].first, A[i].second, st, ft));
  85.             }
  86.         }
  87.     }
  88.     sort(A.begin(), A.end());
  89.     vector <timeline> min_stack;
  90.     for (int i = 0; i < n; ++i)
  91.     {
  92.         double st = 0.0, ft = 0.0;
  93.         while(!min_stack.empty() && is_under(A[i], min_stack.back()))
  94.         {
  95.             ft = min_stack.back().ftime;
  96.             min_stack.pop_back();
  97.         }
  98.         if(min_stack.empty())
  99.         {
  100.             ft = k;
  101.             min_stack.push_back(timeline(A[i].first, A[i].second, st, ft));
  102.         }
  103.         else
  104.         {
  105.             ft = find_intersection(A[i], min_stack.back());
  106.             if(ft >= st+eps)
  107.             {
  108.                 timeline temp = min_stack.back();
  109.                 min_stack.pop_back();
  110.                 temp.stime = ft;
  111.                 min_stack.push_back(temp);
  112.                 min_stack.push_back(timeline(A[i].first, A[i].second, st, ft));
  113.             }
  114.         }
  115.     }
  116.     reverse(max_stack.begin(), max_stack.end());
  117.     reverse(min_stack.begin(), min_stack.end());
  118.    
  119.     // for (int i = 0; i < max_stack.size(); ++i)
  120.     // {
  121.     //  cout<<max_stack[i].slope<<" "<<max_stack[i].intercept<<" "<<max_stack[i].stime<<" "<<max_stack[i].ftime<<"\n";
  122.     // }
  123.     // cout<<"\n\n";
  124.     // for (int i = 0; i < max_stack.size(); ++i)
  125.     // {
  126.     //  cout<<min_stack[i].slope<<" "<<min_stack[i].intercept<<" "<<min_stack[i].stime<<" "<<min_stack[i].ftime<<"\n";
  127.     // }
  128.     // cout<<"\n\n";
  129.  
  130.     int p1 = 0, p2 = 0;
  131.     double ans = 1e20;
  132.     while(p1 < 2*max_stack.size() && p2 < 2*min_stack.size())
  133.     {
  134.         double t1,t2;
  135.         if(p1 & 1)
  136.             t1 = max_stack[p1/2].ftime;
  137.         else
  138.             t1 = max_stack[p1/2].stime;
  139.  
  140.         if(p2 & 1)
  141.             t2 = min_stack[p2/2].ftime;
  142.         else
  143.             t2 = min_stack[p2/2].stime;
  144.  
  145.         double ft = min(t1,t2);
  146.         double v1 = (max_stack[p1/2].slope*ft)+max_stack[p1/2].intercept;
  147.         double v2 = (min_stack[p2/2].slope*ft)+min_stack[p2/2].intercept;
  148.         ans = min(ans, v1-v2);
  149.         if(abs(t1-t2) < eps)
  150.         {
  151.             p1++;
  152.             p2++;
  153.         }
  154.         else if(t1 < t2)
  155.             p1++;
  156.         else
  157.             p2++;
  158.     }
  159.     cout.precision(6);
  160.     cout<<fixed<<ans<<"\n";
  161.     return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement