Advertisement
Dang_Quan_10_Tin

DOMINATOR

May 11th, 2022
757
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.81 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. using ll = long long;
  5. using ld = long double;
  6.  
  7. constexpr int N = 1e5 + 2;
  8. constexpr ll Inf = 1e17;
  9.  
  10. int n, cnt[N], chain[N], in[N], rev[N], l, m;
  11. int id[N], par[N], beg[N], en[N];
  12. ll a[N], b[N], dp[N];
  13.  
  14. struct ConvexHullTrick
  15. {
  16.     vector<int> line, tre;
  17.     vector<ld> point;
  18.     bool build;
  19.  
  20.     ConvexHullTrick()
  21.     {
  22.         point.emplace_back(-Inf);
  23.         build = false;
  24.     }
  25.  
  26.     void AddEdge(int v)
  27.     {
  28.         tre.emplace_back(v);
  29.     }
  30.  
  31.     ld f(int x, int y)
  32.     {
  33.         return (ld)1.0 * (dp[x] - dp[y]) / (b[y] - b[x]);
  34.     }
  35.  
  36.     void AddLine(int i)
  37.     {
  38.         while (line.size() > 1 || (line.size() == 1 && b[line.back()] == b[i] && dp[line.back()] > dp[i]))
  39.         {
  40.             if (b[line.back()] != b[i])
  41.             {
  42.                 if (f(i, line[line.size() - 2]) >= f(i, line.back()))
  43.                 {
  44.                     line.pop_back();
  45.                     if (!line.empty())
  46.                         point.pop_back();
  47.                 }
  48.                 else
  49.                     break;
  50.             }
  51.             else
  52.             {
  53.                 if (dp[i] < dp[line.back()])
  54.                 {
  55.  
  56.                     line.pop_back();
  57.                     if (!line.empty())
  58.                         point.pop_back();
  59.                 }
  60.                 else
  61.                     break;
  62.             }
  63.         }
  64.  
  65.         if (line.empty() || b[i] != b[line.back()])
  66.         {
  67.             if (!line.empty())
  68.                 point.emplace_back(f(i, line.back()));
  69.             line.emplace_back(i);
  70.         }
  71.     }
  72.  
  73.     void construct()
  74.     {
  75.         for (auto i : tre)
  76.             AddLine(i);
  77.  
  78.         build = 1;
  79.     }
  80.  
  81.     ll Get(const ll &r)
  82.     {
  83.         if (line.empty())
  84.             return Inf;
  85.         int j = lower_bound(point.begin(), point.end(), r) - point.begin() - 1;
  86.         return b[line[j]] * r + dp[line[j]];
  87.     }
  88. };
  89.  
  90. struct SegmentTree
  91. {
  92.     ConvexHullTrick st[N * 4];
  93.  
  94.     void Update(int id, int l, int r, const int &a, const int &b, const int &v)
  95.     {
  96.         if (l > b || r < a)
  97.             return;
  98.         if (l >= a && r <= b)
  99.         {
  100.             st[id].AddEdge(v);
  101.             return;
  102.         }
  103.  
  104.         Update(id << 1, l, (l + r) / 2, a, b, v);
  105.         Update(id << 1 | 1, (l + r) / 2 + 1, r, a, b, v);
  106.     }
  107.  
  108.     void Update(int l, int r, int v)
  109.     {
  110.         Update(1, 1, n, l, r, v);
  111.         //cerr << l << " " << r << " " << v << "\n";
  112.     }
  113.  
  114.     ll Get(int id, int l, int r, const int &x, const ll &v)
  115.     {
  116.         if (l > x || r < x)
  117.             return Inf;
  118.  
  119.         if (!st[id].build)
  120.             st[id].construct();
  121.  
  122.         ll ans = st[id].Get(v);
  123.  
  124.         if (l == r)
  125.             return ans;
  126.  
  127.         return min(ans, min(Get(id << 1, l, (l + r) / 2, x, v), Get(id << 1 | 1, (l + r) / 2 + 1, r, x, v)));
  128.     }
  129.  
  130.     ll Get(int id)
  131.     {
  132.         return Get(1, 1, n, id, a[rev[id]]);
  133.     }
  134. } f;
  135.  
  136. vector<int> adj[N];
  137.  
  138. void Read()
  139. {
  140.     cin >> n;
  141.  
  142.     for (int i = 1; i <= n; ++i)
  143.         cin >> a[id[i] = i];
  144.     for (int i = 1; i <= n; ++i)
  145.         cin >> b[i];
  146.  
  147.     for (int i = 1; i < n; ++i)
  148.     {
  149.         int u, v;
  150.         cin >> u >> v;
  151.         adj[u].emplace_back(v);
  152.         adj[v].emplace_back(u);
  153.     }
  154. }
  155.  
  156. void dfs(int v, int p = 0)
  157. {
  158.     par[v] = p;
  159.     cnt[v] = 1;
  160.  
  161.     for (int i = adj[v].size() - 1; ~i; --i)
  162.         if (adj[v][i] == p)
  163.         {
  164.             adj[v][i] = adj[v].back();
  165.             adj[v].pop_back();
  166.         }
  167.         else
  168.         {
  169.             dfs(adj[v][i], v);
  170.             cnt[v] += cnt[adj[v][i]];
  171.         }
  172. }
  173.  
  174. void hld(int v)
  175. {
  176.     //cerr << v << " ";
  177.     chain[v] = m;
  178.     in[v] = ++l;
  179.     rev[in[v]] = v;
  180.     if (!beg[m])
  181.         beg[m] = in[v];
  182.     en[m] = in[v];
  183.  
  184.     pair<int, int> s = {0, 0};
  185.  
  186.     for (auto i : adj[v])
  187.         s = max(s, make_pair(cnt[i], i));
  188.  
  189.     if (s.first)
  190.         hld(s.second);
  191.  
  192.     for (auto i : adj[v])
  193.         if (i != s.second)
  194.         {
  195.             ++m;
  196.             hld(i);
  197.         }
  198. }
  199.  
  200. void Update(int x)
  201. {
  202.     int v = x;
  203.     x = par[x];
  204.     while (x)
  205.     {
  206.         f.Update(beg[chain[x]], in[x], v);
  207.         x = par[rev[beg[chain[x]]]];
  208.     }
  209. }
  210.  
  211. void Solve()
  212. {
  213.     dfs(1);
  214.     m = 1;
  215.     hld(1);
  216.  
  217.     //cerr << "\n";
  218.  
  219.     sort(id + 1, id + n + 1, [&](const int &x, const int &y)
  220.          { return b[x] > b[y] || (b[x] == b[y] && in[x] < in[y]); });
  221.  
  222.     for (int i = 1; i <= n; ++i)
  223.         Update(id[i]);
  224.  
  225.     for (int i = n; i; --i)
  226.         dp[rev[i]] = adj[rev[i]].empty() ? 0 : f.Get(i);
  227.  
  228.     for (int i = 1; i <= n; ++i)
  229.         cout << dp[i] << " ";
  230. }
  231.  
  232. int32_t main()
  233. {
  234.     ios::sync_with_stdio(0);
  235.     cin.tie(0);
  236.     cout.tie(0);
  237.         Read();
  238.         Solve();
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement