```go
package main
import (
"bufio"
"io"
"os"
"strconv"
)
type Line struct {
m, c int64
}
type Node struct {
ln Line
left, right *Node
}
type LiChao struct {
root *Node
l, r int64
}
func eval(ln Line, x int64) int64 {
return ln.m*x + ln.c
}
func (lc *LiChao) add(n *Node, l, r int64, nw Line) *Node {
if n == nil {
return &Node{ln: nw}
}
m := (l + r) >> 1
leftBetter := eval(nw, l) < eval(n.ln, l)
midBetter := eval(nw, m) < eval(n.ln, m)
if midBetter {
n.ln, nw = nw, n.ln
}
if l == r {
return n
}
if leftBetter != midBetter {
n.left = lc.add(n.left, l, m, nw)
} else {
n.right = lc.add(n.right, m+1, r, nw)
}
return n
}
func (lc *LiChao) AddLine(ln Line) {
lc.root = lc.add(lc.root, lc.l, lc.r, ln)
}
func (lc *LiChao) query(n *Node, l, r, x int64) int64 {
res := eval(n.ln, x)
if l == r {
return res
}
m := (l + r) >> 1
if x <= m && n.left != nil {
v := lc.query(n.left, l, m, x)
if v < res {
res = v
}
} else if x > m && n.right != nil {
v := lc.query(n.right, m+1, r, x)
if v < res {
res = v
}
}
return res
}
func (lc *LiChao) Query(x int64) int64 {
return lc.query(lc.root, lc.l, lc.r, x)
}
type Hull struct {
lc *LiChao
lines []Line
}
func NewHull(l, r int64) *Hull {
return &Hull{lc: &LiChao{l: l, r: r}, lines: make([]Line, 0)}
}
func (h *Hull) Add(line Line) {
h.lc.AddLine(line)
h.lines = append(h.lines, line)
}
func (h *Hull) Merge(other *Hull) {
if other == nil || len(other.lines) == 0 {
return
}
for _, ln := range other.lines {
h.Add(ln)
}
}
var data []byte
var idx int
func nextInt64() int64 {
n := len(data)
for idx < n && (data[idx] < '0' || data[idx] > '9') && data[idx] != '-' {
idx++
}
sign := int64(1)
if idx < n && data[idx] == '-' {
sign = -1
idx++
}
val := int64(0)
for idx < n && data[idx] >= '0' && data[idx] <= '9' {
val = val*10 + int64(data[idx]-'0')
idx++
}
return val * sign
}
func main() {
reader := bufio.NewReaderSize(os.Stdin, 1<<20)
bs, _ := io.ReadAll(reader)
data = bs
n := int(nextInt64())
a := make([]int64, n+1)
b := make([]int64, n+1)
minA, maxA := int64(0), int64(0)
for i := 1; i <= n; i++ {
a[i] = nextInt64()
if i == 1 {
minA, maxA = a[i], a[i]
} else {
if a[i] < minA {
minA = a[i]
}
if a[i] > maxA {
maxA = a[i]
}
}
}
for i := 1; i <= n; i++ {
b[i] = nextInt64()
}
g := make([][]int, n+1)
for i := 0; i < n-1; i++ {
u := int(nextInt64())
v := int(nextInt64())
g[u] = append(g[u], v)
g[v] = append(g[v], u)
}
parent := make([]int, n+1)
order := make([]int, 0, n)
stack := make([]int, 0, n)
stack = append(stack, 1)
parent[1] = 0
for len(stack) > 0 {
v := stack[len(stack)-1]
stack = stack[:len(stack)-1]
order = append(order, v)
for _, w := range g[v] {
if w == parent[v] {
continue
}
parent[w] = v
stack = append(stack, w)
}
}
dp := make([]int64, n+1)
hulls := make([]*Hull, n+1)
for i := len(order) - 1; i >= 0; i-- {
v := order[i]
var base *Hull
for _, w := range g[v] {
if w == parent[v] {
continue
}
h := hulls[w]
if h == nil {
continue
}
if base == nil || len(h.lines) > len(base.lines) {
base = h
}
}
for _, w := range g[v] {
if w == parent[v] {
continue
}
h := hulls[w]
if h == nil || h == base {
continue
}
base.Merge(h)
hulls[w] = nil
}
if base == nil || len(base.lines) == 0 {
dp[v] = 0
} else {
dp[v] = base.lc.Query(a[v])
}
curLine := Line{m: b[v], c: dp[v]}
if base == nil {
base = NewHull(minA, maxA)
}
base.Add(curLine)
hulls[v] = base
for _, w := range g[v] {
if w == parent[v] {
continue
}
hulls[w] = nil
}
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
for i := 1; i <= n; i++ {
if i > 1 {
out.WriteByte(' ')
}
out.WriteString(strconv.FormatInt(dp[i], 10))
}
out.WriteByte('\n')
out.Flush()
}
```