func_code_string: #include <bits/stdc++.h>   using namespace std;   const long long maxn = 1e5 + 10, tsz = 5 * maxn, offset = 1e5;   vector<int> graph[maxn];   int sz[maxn];   bool big[maxn];   int a[maxn], b[maxn];   long long dp[maxn];   struct Line {     int m;     long long c;   } tree[tsz];   int Left[tsz], Right[tsz], idn = 1, track[tsz], idt = 0;   bool exist[tsz];   inline long long f(Line &line, long long x) {     return (long long)line.m * (x - offset) + line.c;   }   void add_line(long long lo, long long hi, Line line, long long node) {     if (!exist[node]) track[idt++] = node;     exist[node] = 1;     if (lo == hi) {       if (f(line, lo) < f(tree[node], lo)) tree[node] = line;       return;     }     long long mid = lo + hi >> 1;     bool l = f(line, lo) < f(tree[node], lo);     bool m = f(line, mid) < f(tree[node], mid);     if (m) swap(tree[node], line);     if (l != m) {       if (!Left[node]) Left[node] = ++idn;       add_line(lo, mid, line, Left[node]);     } else {       if (!Right[node]) Right[node] = ++idn;       add_line(mid + 1, hi, line, Right[node]);     }   }   long long query(long long lo, long long hi, long long p, long long node) {     if (lo == hi) return f(tree[node], p);     long long mid = lo + hi >> 1, ret = f(tree[node], p);     if (p <= mid && Left[node])       ret = min(ret, query(lo, mid, p, Left[node]));     else if (p > mid && Right[node])       ret = min(ret, query(mid + 1, hi, p, Right[node]));     return ret;   }   void szdfs(long long u, long long p) {     sz[u] = 1;     for (long long i = 0; i < graph[u].size(); i++) {       long long nd = graph[u][i];       if (nd == p) continue;       szdfs(nd, u);       sz[u] += sz[nd];     }   }   void add(long long u, long long p) {     for (auto v : graph[u]) {       if (v != p && !big[v]) {         add_line(0, maxn + offset, {b[v], dp[v]}, 1);         add(v, u);       }     }   }   void dfs(long long u, long long p, bool keep) {     long long mx = -1, bigChild = -1;     for (auto v : graph[u])       if (v != p && sz[v] > mx) mx = sz[v], bigChild = v;     for (auto v : graph[u])       if (v != p && v != bigChild) dfs(v, u, 0);     if (bigChild != -1) {       dfs(bigChild, u, 1);       big[bigChild] = 1;     }     add(u, p);     if (graph[u].size() == 1 && u != 1)       dp[u] = 0;     else       dp[u] = query(0, maxn + offset, a[u] + offset, 1);     if (keep) add_line(0, maxn + offset, {b[u], dp[u]}, 1);     if (bigChild != -1) big[bigChild] = 0;     if (keep == 0) {       idn = 1;       while (idt) {         int node = track[--idt];         tree[node] = {0, (1LL << 62)};         exist[node] = Left[node] = Right[node] = 0;       }     }   }   int main() {     for (long long i = 0; i < tsz; ++i) tree[i] = {0, (1LL << 62)};     long long n;     cin >> n;     for (long long i = 1; i <= n; ++i) scanf( %d , &a[i]);     for (long long i = 1; i <= n; ++i) scanf( %d , &b[i]);     for (long long i = 1; i < n; i++) {       long long u, v;       scanf( %lld , &u), scanf( %lld , &v);       graph[u].push_back(v);       graph[v].push_back(u);     }     szdfs(1, -1);     dfs(1, -1, 0);     for (long long i = 1; i <= n; ++i) {       if (i != 1) printf(   );       printf( %lld , dp[i]);     }     printf(  n );     return 0;   }   