Advertisement
erek1e

IOI '07 P3 - Sails

Jun 26th, 2023
731
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.32 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <set>
  5. #include <cassert>
  6.  
  7. using namespace std;
  8.  
  9. int H = 0;
  10.  
  11. struct Segment {
  12.     int bottom, top;
  13.     Segment() {}
  14.     Segment(int mn, int mx): bottom(mn), top(mx) {}
  15.     bool operator < (const Segment &s2) const {
  16.         return pair<int, int>(bottom, top) < pair<int, int>(s2.bottom, s2.top);
  17.     }
  18. };
  19.  
  20. int main() {
  21.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  22.     int n; cin >> n;
  23.     vector<pair<int, int>> masts(n);
  24.     for (auto &[h, k] : masts) cin >> h >> k, H = max(H, h);
  25.     sort(masts.begin(), masts.end());
  26.  
  27.     set<Segment> segments; // segments of heights with equal number of sails
  28.     segments.emplace(1, H);
  29.    
  30.     vector<int> adjDifference(1+H+1); // between number of sails on each height
  31.     auto rangeIncrement = [&adjDifference](int first, int last) { // [first, last)
  32.         ++adjDifference[first];
  33.         --adjDifference[last];
  34.     };
  35.  
  36.     for (auto [h, k] : masts) {
  37.         // add 1 to suffix of heights from h to h-k+1, but move the increments
  38.         // in the last (partially covered) segment to the end of that segment
  39.         auto it = segments.lower_bound({h-k+1, H+1});
  40.  
  41.         if (it != segments.begin()) {
  42.             --it;
  43.             int c = k - max(h - it->top, 0); // number in last segment
  44.             assert(c > 0);
  45.            
  46.             // reposition to end
  47.             //  +1 in range [it->bottom, it->bottom+c)
  48.             rangeIncrement(it->bottom, it->bottom+c);
  49.             k -= c;
  50.  
  51.             // update segments
  52.             int f1 = it->bottom, l1 = it->bottom+c-1;
  53.             int f2 = it->bottom+c, l2 = it->top;
  54.             it = segments.erase(it);
  55.             if (f2 <= l2) it = segments.emplace(f2, l2).first;
  56.  
  57.             if (f1 > 1 && !adjDifference[f1]) { // incremented segment has equal value with previous segment
  58.                 // merge
  59.                 --it;
  60.                 int oldFirst = it->bottom;
  61.                 assert(it->top+1 == f1);
  62.                 segments.erase(it);
  63.                 segments.emplace(oldFirst, l1);
  64.             } else segments.emplace(f1, l1);
  65.         }
  66.  
  67.         if (k) {
  68.             // +1 in range [h-k+1, h]
  69.             rangeIncrement(h-k+1, h+1);
  70.  
  71.             //  update segments
  72.             it = prev(segments.end());
  73.             if (h >= it->bottom && h < H) { // need to split 0 segment
  74.                 int b = it->bottom;
  75.                 segments.erase(it);
  76.                 segments.emplace(b, h);
  77.                 segments.emplace(h+1, H);
  78.             }
  79.  
  80.             it = segments.lower_bound({h-k+1, 0}); // first updated segment
  81.             //   if it and prev(it) are now equal, merge them
  82.             if (it->bottom > 1 && !adjDifference[it->bottom]) {
  83.                 // merge
  84.                 int last = it->top;
  85.                 it = prev(segments.erase(it));
  86.                 int first = it->bottom;
  87.                 segments.erase(it);
  88.                 segments.emplace(first, last);
  89.             }
  90.         }
  91.     }
  92.    
  93.     // Determine the total inefficiency of the configuration
  94.     long long totalInefficiency = 0;
  95.     for (int h = 1, sails = 0; h <= H; ++h) {
  96.         sails += adjDifference[h];
  97.         totalInefficiency += sails*(sails-1LL)/2;
  98.     }
  99.     cout << totalInefficiency << endl;
  100.     return 0;
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement