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. }  

Sunday, May 26, 2019

[UVA Live] ACM Tax

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : ACM Tax
Source            : UVA Live
Category          : Data Structure
Algorithm         : Persistent Segment Tree
Verdict           : Accepted

 
  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 1e6 + 5;  
  6. static const int logn = 18;  
  7.   
  8. struct Node  
  9. {  
  10.       int st;  
  11.       int lft, rgt;  
  12.       Node(int st = 0, int lft = 0, int rgt = 0) : st(st), lft(lft), rgt(rgt) {}  
  13. } Tree[maxn];  
  14.   
  15. int version[maxn], NODES, N = 100000 + 5;  
  16.   
  17. int update(int root, int a, int b, int pos, int val)  
  18. {  
  19.       int newNode = ++NODES;  
  20.       Tree[newNode] = Tree[root];  
  21.       if (a == b)  
  22.       {  
  23.             Tree[newNode].st += val;  
  24.             return newNode;  
  25.       }  
  26.       int mid = (a + b) >> 1;  
  27.       if (pos <= mid) Tree[newNode].lft = update(Tree[newNode].lft, a, mid, pos, val);  
  28.       else Tree[newNode].rgt = update(Tree[newNode].rgt, mid + 1, b, pos, val);  
  29.       Tree[newNode].st = Tree[ Tree[newNode].lft ].st + Tree[ Tree[newNode].rgt ].st;  
  30.       return newNode;  
  31. }  
  32.   
  33. int query(int root_lca, int root_u, int root_v, int a, int b, int k)  
  34. {  
  35.       if (a == b) return a;  
  36.       int sum = Tree[ Tree[root_u].lft ].st + Tree[ Tree[root_v].lft ].st - 2 * Tree[ Tree[root_lca].lft ].st;  
  37.       int mid = a + b >> 1;  
  38.       if (sum >= k) return query(Tree[root_lca].lft, Tree[root_u].lft, Tree[root_v].lft, a, mid, k);  
  39.       else return query(Tree[root_lca].rgt, Tree[root_u].rgt, Tree[root_v].rgt, mid+1, b, k - sum);  
  40. }  
  41.   
  42. struct GNode  
  43. {  
  44.       int v, w;  
  45.       GNode(int v = 0, int w = 0) : v(v), w(w) {}  
  46. };  
  47.   
  48. vector <GNode> graph[maxn];  
  49. int depth[maxn], father[maxn][logn];  
  50.   
  51. void dfs(int u = 1, int p = -1)  
  52. {  
  53.       for (int i = 1; i < logn; i++) father[u][i] = father[ father[u][i-1] ][i-1];  
  54.       for (GNode it : graph[u])  
  55.       {  
  56.             int v = it.v;  
  57.             int w = it.w;  
  58.             if (v == p) continue;  
  59.             depth[v] = depth[u] + 1;  
  60.             father[v][0] = u;  
  61.             version[v] = update(version[u], 1, N, w, 1);  
  62.             dfs(v, u);  
  63.       }  
  64. }  
  65.   
  66. int lca(int u, int v)  
  67. {  
  68.       if (depth[u] < depth[v]) swap(u, v);  
  69.       for (int i = logn-1; i >= 0; i--) if (depth[ father[u][i] ] >= depth[v]) u = father[u][i];  
  70.       if (u == v) return u;  
  71.       for (int i = logn-1; i >= 0; i--) if (father[u][i] != father[v][i]) u = father[u][i], v = father[v][i];  
  72.       return father[u][0];  
  73. }  
  74.   
  75. void clean()  
  76. {  
  77.       NODES = 0;  
  78.       for (int i = 0; i < maxn; i++)  
  79.       {  
  80.             Tree[i] = Node();  
  81.             version[i] = 0;  
  82.             graph[i].clear();  
  83.             depth[i] = 0;  
  84.             fill(begin(father[i]), end(father[i]), 0);  
  85.       }  
  86. }  
  87.   
  88. signed main()  
  89. {  
  90.       ios_base::sync_with_stdio(false);  
  91.       cin.tie(nullptr);  
  92.       cout.tie(nullptr);  
  93.       cout << fixed << setprecision(1);  
  94.   
  95.       #ifndef ONLINE_JUDGE  
  96.             freopen("in.txt""r", stdin);  
  97.       #endif // ONLINE_JUDGE  
  98.   
  99.   
  100.       int tc;  
  101.       cin >> tc;  
  102.       for (int tcase = 1; tcase <= tc; tcase++)  
  103.       {  
  104.             clean();  
  105.   
  106.             int tnode;  
  107.             cin >> tnode;  
  108.             for (int e = 1; e < tnode; e++)  
  109.             {  
  110.                   int u, v, w;  
  111.                   cin >> u >> v >> w;  
  112.                   graph[u].emplace_back(v, w);  
  113.                   graph[v].emplace_back(u, w);  
  114.             }  
  115.             version[0] = 0;  
  116.             version[1] = update(version[0], 1, N, 4, 0);  
  117.             depth[1] = 1;  
  118.             dfs();  
  119.   
  120.             int tqeury;  
  121.             cin >> tqeury;  
  122.             for (int q = 1; q <= tqeury; q++)  
  123.             {  
  124.                   int u, v;  
  125.                   cin >> u >> v;  
  126.                   int lcax = lca(u, v);  
  127.                   int d = depth[u] + depth[v] - 2 * depth[lcax];  
  128.                   int k = (d+1) / 2;  
  129.                   double ans = (double)query(version[lcax], version[u], version[v], 1, N, k);  
  130.                   if (~d & 1)  
  131.                   {  
  132.                         ans += (double)query(version[lcax], version[u], version[v], 1, N, k+1);  
  133.                         ans /= 2.0;  
  134.                   }  
  135.                   cout << ans << '\n';  
  136.             }  
  137.       }  
  138. }