warriorscats

SGT

May 29th, 2020
1,158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.62 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define Dmax 300001
  4. using namespace std;
  5.  
  6. ifstream fin("is.in");
  7. ofstream fout("is.out");
  8.  
  9. struct entry    /// Structure for storing the states of the sweeping line array
  10. {
  11.     int x, y1, y2, sgn;
  12. } A[Dmax]; /// The sweeping line array
  13.  
  14. inline int max(int a, int b)    /// Utility function
  15. {
  16.     return (a > b ? a : b);
  17. }
  18.  
  19. int N, T[Dmax << 2];
  20. long long Res;
  21.  
  22. inline int cmp(const void *i, const void *j)    /// Comparator function
  23. {
  24.     entry *ei = (entry *) i, *ej = (entry *) j;
  25.  
  26.     if (ei->x != ej->x)
  27.         return ei->x - ej->x;
  28.  
  29.     return ej->sgn - ei->sgn;
  30. }
  31.  
  32. inline int query(int n, int l, int r, int a, int b)     /// Query function for the segment tree
  33. {
  34.     int m, t = 0;
  35.  
  36.     if (a <= l && r <= b)
  37.         return T[n];
  38.     else
  39.     {
  40.         m = (l + r) / 2;
  41.         if (a <= m)
  42.             t += query(2 * n, l, m, a, b);
  43.         if (b > m)
  44.             t += query(2 * n + 1, m + 1, r, a, b);
  45.     }
  46.  
  47.     return t;
  48. }
  49.  
  50. inline void update(int n, int l, int r, int p, int v)   /// Update function for the segment tree
  51. {
  52.     int m = (l + r) / 2;
  53.     T[n] += v;
  54.  
  55.     if (l == r) return;
  56.  
  57.     if (p <= m)
  58.         update(2 * n, l, m, p, v);
  59.     else
  60.         update(2 * n + 1, m + 1, r, p, v);
  61. }
  62.  
  63. int main()  /// Driver function
  64. {
  65.     int i, n, x1, y1, x2, y2, MaxC = INT_MIN;
  66.     fin >>  N;
  67.  
  68.     for (n = i = 0; i < N; i++) /// Read the input file
  69.     {
  70.         fin >> x1 >> y1 >> x2 >> y2;
  71.  
  72.         if (y1 == y2)       /// The given segment is horizontal
  73.             A[n].x = x1, A[n].sgn = +1,
  74.             A[n++].y1 = y1,
  75.             A[n].x = x2, A[n].sgn = -1,
  76.             A[n++].y1 = y1;
  77.         else if (x1 == x2)  /// The given segment is vertical
  78.             A[n].x = x1, A[n].sgn = 0,
  79.             A[n].y1 = y1, A[n++].y2 = y2;
  80.  
  81.         int crt = max(y1, y2);
  82.         MaxC = max(MaxC, crt);
  83.     }
  84.     fin.close();
  85.  
  86.     qsort(A, n, sizeof(entry), cmp);    /// Sort the sweeping line array
  87.  
  88.     for (i = 0; i < n; i++) /// Iterate through all the states of the sweeping line array
  89.         if (A[i].sgn == 0)  /// If the current state is a sweeping line ,i.e. a vertical segment then
  90.             Res += query(1, 0, MaxC, A[i].y1, A[i].y2); /// Start a query for the interval [y1, y2] to check how many segments cross the sweeping line
  91.         else    /// Else if the current state is a horizontal segment then
  92.             update(1, 0, MaxC, A[i].y1, A[i].sgn);  /// Update its current state through the entire segment tree ,i.e. push it or pop it from the tree
  93.  
  94.     fout << Res; /// Return the output result
  95.     fout.close();
  96.  
  97.     return 0;
  98. }
Add Comment
Please, Sign In to add comment