Monday, December 10, 2018

[UVa Live Archive] 5871 - Arnooks's Defensive Line

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 5871 - Arnooks's Defensive Line
Source            : UVa Live Archive
Category          : Divide and Conquer
Algorithm         : solving Insert-Query Problems Offline
Verdict           : Accepted
  1. #include "bits/stdc++.h"  
  2. #include "ext/pb_ds/assoc_container.hpp"  
  3. #include "ext/pb_ds/tree_policy.hpp"  
  4.    
  5. using namespace std;  
  6. using namespace __gnu_pbds;  
  7.    
  8. template <typename T> using orderSet = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;  
  9.    
  10. #define ll                    long long  
  11. #define pii                   pair <int, int>  
  12. #define pll                   pair <ll, ll>  
  13. #define all(a)                a.begin(), a.end()  
  14. #define eb                    emplace_back  
  15.    
  16. static const int maxn = 5e5 + 5;  
  17.    
  18. struct info  
  19. {  
  20.     int type, pos;  
  21.     ll l, r;  
  22.     info(int type = 0, int pos = 0, ll l = 0, ll r = 0)  
  23.     {  
  24.         this->type = type;  
  25.         this->pos = pos;  
  26.         this->l = l;  
  27.         this->r = r;  
  28.     }  
  29. } arr[maxn];  
  30.    
  31. bool comp(const info &A, const info &B)  
  32. {  
  33.     if (A.l == B.l) return A.r < B.r;  
  34.     return A.l < B.l;  
  35. }  
  36.    
  37. vector <info> Insert, Query;  
  38. orderSet <pll> X;  
  39. ll ans[maxn];  
  40.    
  41. void solve()  
  42. {  
  43.     sort(all(Insert), comp);  
  44.     sort(all(Query), comp);  
  45.     int leni = Insert.size();  
  46.     int lenq = Query.size();  
  47.     int i = 0;  
  48.     ll id = 0;  
  49.     for (int j = 0; j < lenq; j++)  
  50.     {  
  51.         while (i < leni && Insert[i].l <= Query[j].l)  
  52.         {  
  53.             X.insert({Insert[i].r, ++id});  
  54.             i++;  
  55.         }  
  56.         ll cnt = X.size() - X.order_of_key({Query[j].r, -1});  
  57.         ans[ Query[j].pos ] += cnt;  
  58.     }  
  59.     Insert.clear();  
  60.     Query.clear();  
  61.     X.clear();  
  62. }  
  63.    
  64. void divideConquer(int l, int r)  
  65. {  
  66.     if (l >= r) return;  
  67.     int mid = (l + r) >> 1;  
  68.     for (int i = l; i <= mid; i++)  
  69.     {  
  70.         if (arr[i].type == 0) // insert  
  71.             Insert.eb(arr[i]);  
  72.     }  
  73.     for (int i = mid+1; i <= r; i++)  
  74.     {  
  75.         if (arr[i].type == 1) // query  
  76.             Query.eb(arr[i]);  
  77.     }  
  78.     solve();  
  79.     divideConquer(l, mid);  
  80.     divideConquer(mid+1, r);  
  81. }  
  82.    
  83.    
  84. int main()  
  85. {  
  86.     //freopen("in.txt", "r", stdin);  
  87.    
  88.     int N;  
  89.     cin >> N;  
  90.     int pos = 0;  
  91.     for (int i = 1; i <= N; i++)  
  92.     {  
  93.         char type;  
  94.         ll l, r;  
  95.         cin >> type >> l >> r;  
  96.         if (l > r) swap(l, r);  
  97.         if (type == '+') arr[i] = info(0, 0, l, r);  
  98.         else arr[i] = info(1, ++pos, l, r);  
  99.     }  
  100.     divideConquer(1, N);  
  101.     for (int i = 1; i <= pos; i++) cout << ans[i] << endl;  
  102. }  
 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.