Friday, May 31, 2019

[Codeforces] F. Escape Through Leaf

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : F. Escape Through Leaf
Source            : Codeforces
Category          : Data Structure
Algorithm         : Dynamic Convex Hull Trick
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll              long long int  
  6.   
  7. static const int maxn = 2e5 + 5;  
  8.   
  9. // Dynamic Convex Hull Trick  
  10. // Keeps upper hull for maximums.  
  11. // add lines with -m and -b and return -ans to get minimums  
  12. // source : https://codeforces.com/blog/entry/11155?#comment-162462  
  13.   
  14. static const ll is_query = LLONG_MIN;  
  15.   
  16. struct Line  
  17. {  
  18.       ll m, b;  
  19.       mutable function <const Line*()> succ;  
  20.       bool operator < (const Line &rhs) const  
  21.       {  
  22.             if (rhs.b != is_query) return m < rhs.m;  
  23.             const Line *s = succ();  
  24.             if (!s) return 0;  
  25.             ll x = rhs.m;  
  26.             return (b - s->b) < ((s->m - m) * x);  
  27.       }  
  28. };  
  29.   
  30. struct CHT : public multiset <Line>  
  31. {  
  32.       bool bad(iterator y)  
  33.       {  
  34.             auto z = next(y);  
  35.             if (y == begin())  
  36.             {  
  37.                   if (z == end()) return 0;  
  38.                   return y->m == z->m && y->b <= z->b;  
  39.             }  
  40.             auto x = prev(y);  
  41.             if (z == end()) return y->m == x->m && y->b <= x->b;  
  42.             return 1.0 * (x->b - y->b) * (z->m - y->m) >= 1.0 * (y->b - z->b) * (y->m - x->m);  
  43.       }  
  44.       void add(ll m, ll b)  
  45.       {  
  46.             auto y = insert({m, b});  
  47.             y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };  
  48.             if (bad(y)) { erase(y); return; }  
  49.             while (next(y) != end() && bad(next(y))) erase(next(y));  
  50.             while (y != begin() && bad(prev(y))) erase(prev(y));  
  51.       }  
  52.       ll query(ll x)  
  53.       {  
  54.             auto l = *lower_bound((Line){x, is_query} );  
  55.             return l.m * x + l.b;  
  56.       }  
  57. };  
  58.   
  59. CHT *cht[maxn];  
  60.   
  61. vector <int> graph[maxn];  
  62. ll a[maxn], b[maxn], ans[maxn];  
  63.   
  64. void dfs(int u = 1, int p = -1)  
  65. {  
  66.       int sze = 0;  
  67.       cht[u] = new CHT();  
  68.       for (int v : graph[u])  
  69.       {  
  70.             if (v == p) continue;  
  71.             ++sze;  
  72.             dfs(v, u);  
  73.             // Merge smaller to bigger  
  74.             if ((*cht[u]).size() < (*cht[v]).size()) swap(cht[u], cht[v]);  
  75.             for (auto x : (*cht[v])) (*cht[u]).add(x.m, x.b);  
  76.             (*cht[v]).clear();  
  77.       }  
  78.       if (sze == 0) ans[u] = 0;  
  79.       else ans[u] = -(*cht[u]).query(a[u]);  
  80.       (*cht[u]).add(-b[u], -ans[u]);  
  81. }  
  82.   
  83. signed main()  
  84. {  
  85.       ios_base::sync_with_stdio(false);  
  86.       cin.tie(nullptr);  
  87.       cout.tie(nullptr);  
  88.   
  89.       #ifndef ONLINE_JUDGE  
  90.             freopen("in.txt""r", stdin);  
  91.       #endif // ONLINE_JUDGE  
  92.   
  93.       int tnode;  
  94.       cin >> tnode;  
  95.       for (int i = 1; i <= tnode; i++) cin >> a[i];  
  96.       for (int i = 1; i <= tnode; i++) cin >> b[i];  
  97.       for (int e = 1; e < tnode; e++)  
  98.       {  
  99.             int u, v;  
  100.             cin >> u >> v;  
  101.             graph[u].emplace_back(v);  
  102.             graph[v].emplace_back(u);  
  103.       }  
  104.       dfs();  
  105.       for (int i = 1; i <= tnode; i++) cout << ans[i] << ' ';  
  106. }  

No comments:

Post a Comment

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