Saturday, April 4, 2020

[Codeforces] F. Lena and Queries

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : F. Lena and Queries
Source            : Codeforces
Category          : Data Structure, Dynamic Programing
Algorithm         : Dynamic Connectivity, DP Optimization
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll            long long int  
  6. #define endl          '\n'  
  7. #define pll           pair <ll, ll>  
  8. #define mk            make_pair  
  9.   
  10. static const int maxn = 4e5 + 5;  
  11. static const ll is_query = LLONG_MIN;  
  12.   
  13. struct Line  
  14. {  
  15.       ll m, b;  
  16.       mutable function <const Line*()> succ;  
  17.       bool operator < (const Line &rhs) const  
  18.       {  
  19.             if (rhs.b != is_query) return m < rhs.m;  
  20.             const Line *s = succ();  
  21.             if (!s) return 0;  
  22.             ll x = rhs.m;  
  23.             return (b - s->b) < ((s->m - m) * x);  
  24.       }  
  25. };  
  26.   
  27. struct CHT : public multiset <Line>  
  28. {  
  29.       bool bad(iterator y)  
  30.       {  
  31.             auto z = next(y);  
  32.             if (y == begin())  
  33.             {  
  34.                   if (z == end()) return 0;  
  35.                   return y->m == z->m && y->b <= z->b;  
  36.             }  
  37.             auto x = prev(y);  
  38.             if (z == end()) return y->m == x->m && y->b <= x->b;  
  39.             return 1.0 * (x->b - y->b) * (z->m - y->m) >= 1.0 * (y->b - z->b) * (y->m - x->m);  
  40.       }  
  41.       void add(ll m, ll b)  
  42.       {  
  43.             auto y = insert({m, b});  
  44.             y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };  
  45.             if (bad(y)) { erase(y); return; }  
  46.             while (next(y) != end() && bad(next(y))) erase(next(y));  
  47.             while (y != begin() && bad(prev(y))) erase(prev(y));  
  48.       }  
  49.       ll query(ll x)  
  50.       {  
  51.             auto l = *lower_bound((Line){x, is_query});  
  52.             return l.m * x + l.b;  
  53.       }  
  54. };  
  55.   
  56. vector < vector <pll> > Tree(4 * maxn);  
  57.   
  58. void update(int node, int a, int b, int i, int j, pll p)  
  59. {  
  60.       if (a > j or b < i) return;  
  61.       if (a >= i and b <= j) return void(Tree[node].push_back(p));  
  62.       int lchild = node * 2;  
  63.       int rchild = lchild + 1;  
  64.       int mid = (a + b) / 2;  
  65.       update(lchild, a, mid, i, j, p);  
  66.       update(rchild, mid + 1, b, i, j, p);  
  67. }  
  68.   
  69. vector < CHT* > cht(30);  
  70. vector <ll> qval(maxn);  
  71. vector <bool> valid(maxn);  
  72. vector <ll> ans(maxn);  
  73. vector <bool> isquery(maxn);  
  74.   
  75. void dfs(int node, int a, int b, int h)  
  76. {  
  77.       if (a > b) return;  
  78.       cht[h] = new CHT();  
  79.       for (pll p : Tree[node]) (*cht[h]).add(p.first, p.second);  
  80.       if (a == b)  
  81.       {  
  82.             if (isquery[a] == 0) return;  
  83.             ll maxi = is_query;  
  84.             for (int i = 0; i <= h; i++)  
  85.             {  
  86.                   if ((*cht[i]).size() == 0) continue;  
  87.                   ll dp = (*cht[i]).query(qval[a]);  
  88.                   maxi = max(maxi, dp);  
  89.                   valid[a] = 1;  
  90.             }  
  91.             ans[a] = maxi;  
  92.       }  
  93.       else  
  94.       {  
  95.             int lchild = node * 2;  
  96.             int rchild = lchild + 1;  
  97.             int mid = (a + b) / 2;  
  98.             dfs(lchild, a, mid, h + 1);  
  99.             dfs(rchild, mid + 1, b, h + 1);  
  100.       }  
  101. }  
  102.   
  103. signed main()  
  104. {  
  105.       ios_base::sync_with_stdio(false);  
  106.       cin.tie(nullptr);  
  107.   
  108.       #ifndef ONLINE_JUDGE  
  109.             freopen("in.txt""r", stdin);  
  110.       #endif // ONLINE_JUDGE  
  111.   
  112.       int n;  
  113.       cin >> n;  
  114.       map <pll, int> in;  
  115.       vector <pll> all_queries(n + 1);  
  116.       for (int i = 1; i <= n; i++)  
  117.       {  
  118.             int type;  
  119.             cin >> type;  
  120.             if (type == 1)  
  121.             {  
  122.                   ll a, b;  
  123.                   cin >> a >> b;  
  124.                   in[mk(a, b)] = i;  
  125.                   all_queries[i] = mk(a, b);  
  126.             }  
  127.             else if (type == 2)  
  128.             {  
  129.                   int id;  
  130.                   cin >> id;  
  131.                   ll a = all_queries[id].first;  
  132.                   ll b = all_queries[id].second;  
  133.                   int l = in[mk(a, b)];  
  134.                   int r = i - 1;  
  135.                   update(1, 1, n, l, r, mk(a, b));  
  136.                   in.erase(mk(a, b));  
  137.             }  
  138.             else  
  139.             {  
  140.                   ll val;  
  141.                   cin >> val;  
  142.                   qval[i] = val;  
  143.                   isquery[i] = 1;  
  144.             }  
  145.       }  
  146.       for (auto it : in)  
  147.       {  
  148.             int l = it.second;  
  149.             int r = n;  
  150.             ll a = it.first.first;  
  151.             ll b = it.first.second;  
  152.             update(1, 1, n, l, r, mk(a, b));  
  153.       }  
  154.       dfs(1, 1, n, 0);  
  155.       for (int i = 1; i <= n; i++)  
  156.       {  
  157.             if (isquery[i] == 0) continue;  
  158.             if (valid[i]) cout << ans[i] << '\n';  
  159.             else cout << "EMPTY SET" << '\n';  
  160.       }  
  161. }  

No comments:

Post a Comment

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