Advertisement
despotovski01

Барок 2

Aug 2nd, 2017
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.99 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5.  
  6. ll min(ll a, ll b, ll c, ll d)
  7. {
  8.     return min(a, min(b, min(c, d)));
  9. }
  10.  
  11. ll max(ll a, ll b, ll c, ll d)
  12. {
  13.     return max(a, max(b, max(c, d)));
  14. }
  15.  
  16. template <typename T>
  17. int cmp(T& a, T& b)
  18. {
  19.     if(a < b)
  20.     {
  21.         return -1;
  22.     }
  23.     else if(a > b)
  24.     {
  25.         return 1;
  26.     }
  27.     return 0;
  28. }
  29.  
  30. class Segment
  31. {
  32. public:
  33.     ll left, right;
  34.  
  35.     Segment(ll left = 0LL, ll right = 0LL)
  36.     {
  37.         this->left = left;
  38.         this->right = right;
  39.     }
  40.  
  41.     bool intersectsWith(const Segment& other)
  42.     {
  43.         bool thisCheck = (left >= other.left && left <= other.right) || (right >= other.left && right <= other.right);
  44.         bool otherCheck = (other.left >= left && other.left <= right) || (other.right >= left && other.right <= right);
  45.         return thisCheck || otherCheck;
  46.     }
  47.  
  48.     Segment getUnion(const Segment& other)
  49.     {
  50.         ll uLeft = min(left, right, other.left, other.right);
  51.         ll uRight = max(left, right, other.left, other.right);
  52.         return Segment(uLeft, uRight);
  53.     }
  54.  
  55.     ll getLength()
  56.     {
  57.         return right - left + 1;
  58.     }
  59.  
  60.     string toString()
  61.     {
  62.         stringstream ss;
  63.         ss<<"{"<<left<<", "<<right<<"}";
  64.         return ss.str();
  65.     }
  66.  
  67.     bool operator <(const Segment& other) const
  68.     {
  69.         int res = cmp(left, other.left);
  70.         if(res == 0)
  71.         {
  72.             res = cmp(right, other.right);
  73.         }
  74.         return res < 0;
  75.     }
  76.  
  77.     bool operator >(const Segment& other) const
  78.     {
  79.         int res = cmp(left, other.left);
  80.         if(res == 0)
  81.         {
  82.             res = cmp(right, other.right);
  83.         }
  84.         return res > 0;
  85.     }
  86.  
  87.     bool operator ==(const Segment& other) const
  88.     {
  89.         int res = cmp(left, other.left);
  90.         if(res == 0)
  91.         {
  92.             res = cmp(right, other.right);
  93.         }
  94.         return res == 0;
  95.     }
  96. };
  97.  
  98. const int TYPE_RECT_BEGIN = 0;
  99. const int TYPE_RECT_END = 1;
  100.  
  101. class Rectangle {
  102. public:
  103.     Segment horizontalSegment;
  104.     Segment verticalSegment;
  105.  
  106.     Rectangle(ll topLeftX, ll topLeftY, ll bottomRightX, ll bottomRightY)
  107.     {
  108.         horizontalSegment = Segment(topLeftX, bottomRightX);
  109.         verticalSegment = Segment(topLeftY, bottomRightY);
  110.     }
  111.  
  112.     string toString()
  113.     {
  114.         stringstream ss;
  115.         ss<<"Horizontal: "<<horizontalSegment.toString()<<"\tVertical: "<<verticalSegment.toString();
  116.         return ss.str();
  117.     }
  118. };
  119.  
  120. class Event {
  121. public:
  122.     int type;
  123.     ll x;
  124.     Segment verticalSegment;
  125.  
  126.     Event(int type, ll x, Segment verticalSegment)
  127.     {
  128.         this->type = type;
  129.         this->x = x;
  130.         this->verticalSegment = verticalSegment;
  131.     }
  132. };
  133.  
  134. bool horizontalPosCmp(const Event& first, const Event& second)
  135. {
  136.     int res = cmp(first.x, second.x);
  137.     if(res == 0)
  138.     {
  139.         res = cmp(first.type, second.type);
  140.     }
  141.     if(res == 0)
  142.     {
  143.         res = cmp(first.verticalSegment, second.verticalSegment);
  144.     }
  145.     return res < 0;
  146. }
  147.  
  148. vector<Segment> getUnion(vector<Segment> &verticalSegments)
  149. {
  150.     vector<Segment> res;
  151.     vector<bool> used(verticalSegments.size(), false);
  152.     for(int i = 0;i<verticalSegments.size();++i)
  153.     {
  154.         if(!used[i])
  155.         {
  156.             used[i] = true;
  157.             Segment current = verticalSegments[i];
  158.             for(int j = i+1;j<verticalSegments.size();++j)
  159.             {
  160.                 if(current.intersectsWith(verticalSegments[j]))
  161.                 {
  162.                     used[j] = true;
  163.                     current = current.getUnion(verticalSegments[j]);
  164.                 }
  165.             }
  166.             res.push_back(current);
  167.         }
  168.     }
  169.     return res;
  170. }
  171.  
  172. ll getArea(ll width, vector<Segment> &verticalSegments)
  173. {
  174.     ll res = 0;
  175.     vector<Segment> segmentUnion = getUnion(verticalSegments);
  176.     for(Segment& segment: segmentUnion)
  177.     {
  178.         res += width * segment.getLength();
  179.     }
  180.     return res;
  181. }
  182.  
  183. vector<Segment> keysToVector(map<Segment, int> &segments)
  184. {
  185.     vector<Segment> res;
  186.     for(auto it = segments.begin(); it != segments.end(); ++it)
  187.     {
  188.         if(it->second != 0)
  189.         {
  190.             res.push_back(it->first);
  191.         }
  192.     }
  193.     return res;
  194. }
  195.  
  196. int main()
  197. {
  198.     ios::sync_with_stdio(false);
  199.  
  200.     ll height, width;
  201.     cin>>height>>width;
  202.  
  203.     int months;
  204.     cin>>months;
  205.  
  206.     int buildings;
  207.     cin>>buildings;
  208.  
  209.     vector<Event> events;
  210.     for(int i = 0;i<buildings;++i)
  211.     {
  212.         ll x, y;
  213.         cin>>y>>x;
  214.         ll topX = max(1LL, x - months);
  215.         ll topY = max(1LL, y - months);
  216.         ll bottomX = min(width, x + months);
  217.         ll bottomY = min(height, y + months);
  218.         Rectangle rectangle(topX, topY, bottomX, bottomY);
  219.         events.push_back(Event(TYPE_RECT_BEGIN, rectangle.horizontalSegment.left, rectangle.verticalSegment));
  220.         events.push_back(Event(TYPE_RECT_END, rectangle.horizontalSegment.right+1, rectangle.verticalSegment));
  221.     }
  222.     sort(events.begin(), events.end(), horizontalPosCmp);
  223.  
  224.     map<Segment, int> segments;
  225.     ll prevX = 0;
  226.     ll res = 0;
  227.     for(int i = 0;i<events.size();++i)
  228.     {
  229.         Event &event = events[i];
  230.  
  231.         if(i > 0)
  232.         {
  233.             // Add area
  234.             vector<Segment> segmentVector = keysToVector(segments);
  235.             res += getArea(event.x - prevX, segmentVector);
  236.         }
  237.  
  238.         while(events[i].x == event.x && i < events.size())
  239.         {
  240.             // While there are events on this position, process them
  241.             if(events[i].type == TYPE_RECT_BEGIN)
  242.             {
  243.                 // Add vertical segment
  244.                 segments[events[i].verticalSegment]++;
  245.             }
  246.             else
  247.             {
  248.                 // Remove the vertical segment
  249.                 segments[events[i].verticalSegment]--;
  250.             }
  251.             i++;
  252.         }
  253.         i--;
  254.         prevX = event.x;
  255.     }
  256.     cout<<res<<endl;
  257.     return 0;
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement