← Home
For problem statement at 1000-1999/1100-1199/1140-1149/1140/problemG.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1140-1149/1140/verifierG.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"math/bits"
	"os"
	"runtime"
	"strconv"
)

const INF int64 = 1 << 60

type Mat struct {
	a00, a01, a10, a11 int64
}

var idMat = Mat{0, INF, INF, 0}

func mul(x, y Mat) Mat {
	z00 := x.a00 + y.a00
	t := x.a01 + y.a10
	if t < z00 {
		z00 = t
	}
	z01 := x.a00 + y.a01
	t = x.a01 + y.a11
	if t < z01 {
		z01 = t
	}
	z10 := x.a10 + y.a00
	t = x.a11 + y.a10
	if t < z10 {
		z10 = t
	}
	z11 := x.a10 + y.a01
	t = x.a11 + y.a11
	if t < z11 {
		z11 = t
	}
	return Mat{z00, z01, z10, z11}
}

func trans(x Mat) Mat {
	return Mat{x.a00, x.a10, x.a01, x.a11}
}

type FastScanner struct {
	f   *os.File
	buf []byte
	i   int
	n   int
}

func NewFastScanner() *FastScanner {
	return &FastScanner{
		f:   os.Stdin,
		buf: make([]byte, 1<<20),
	}
}

func (fs *FastScanner) read() byte {
	if fs.i >= fs.n {
		n, _ := fs.f.Read(fs.buf)
		if n == 0 {
			return 0
		}
		fs.i = 0
		fs.n = n
	}
	b := fs.buf[fs.i]
	fs.i++
	return b
}

func (fs *FastScanner) NextInt64() int64 {
	b := fs.read()
	for b <= ' ' {
		b = fs.read()
	}
	var sign int64 = 1
	if b == '-' {
		sign = -1
		b = fs.read()
	}
	var v int64
	for b > ' ' {
		v = v*10 + int64(b-'0')
		b = fs.read()
	}
	return v * sign
}

func (fs *FastScanner) NextInt() int {
	return int(fs.NextInt64())
}

func lca(x, y, n1, lg int, depth []int32, anc []uint32) int {
	if depth[x] < depth[y] {
		x, y = y, x
	}
	diff := int(depth[x] - depth[y])
	b := 0
	for diff > 0 {
		if diff&1 != 0 {
			x = int(anc[b*n1+x])
		}
		diff >>= 1
		b++
	}
	if x == y {
		return x
	}
	for k := lg - 1; k >= 0; k-- {
		ax := int(anc[k*n1+x])
		ay := int(anc[k*n1+y])
		if ax != ay {
			x = ax
			y = ay
		}
	}
	return int(anc[x])
}

func prodUp(x, a, n1 int, depth []int32, anc []uint32, mats []Mat) Mat {
	res := idMat
	diff := int(depth[x] - depth[a])
	b := 0
	for diff > 0 {
		if diff&1 != 0 {
			res = mul(res, mats[b*n1+x])
			x = int(anc[b*n1+x])
		}
		diff >>= 1
		b++
	}
	return res
}

func main() {
	fs := NewFastScanner()

	n := fs.NextInt()
	vert := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		vert[i] = fs.NextInt64()
	}

	m := 2 * (n - 1)
	head := make([]int32, n+1)
	for i := 0; i <= n; i++ {
		head[i] = -1
	}
	to := make([]int32, m)
	nxt := make([]int32, m)
	wa := make([]int64, m)
	wb := make([]int64, m)

	var ec int32
	for i := 0; i < n-1; i++ {
		x := fs.NextInt()
		y := fs.NextInt()
		a := fs.NextInt64()
		b := fs.NextInt64()

		to[ec] = int32(y)
		wa[ec] = a
		wb[ec] = b
		nxt[ec] = head[x]
		head[x] = ec
		ec++

		to[ec] = int32(x)
		wa[ec] = a
		wb[ec] = b
		nxt[ec] = head[y]
		head[y] = ec
		ec++
	}

	lg := bits.Len(uint(n))
	n1 := n + 1

	anc := make([]uint32, lg*n1)
	depth := make([]int32, n1)
	parEdge := make([]int32, n1)

	stack := make([]int32, 1, n)
	stack[0] = 1
	order := make([]int32, 0, n)

	for len(stack) > 0 {
		v := int(stack[len(stack)-1])
		stack = stack[:len(stack)-1]
		order = append(order, int32(v))
		pv := int(anc[v])
		for e := head[v]; e != -1; {
			ei := int(e)
			u := int(to[ei])
			ne := nxt[ei]
			if u != pv {
				anc[u] = uint32(v)
				depth[u] = depth[v] + 1
				parEdge[u] = e
				stack = append(stack, int32(u))
			}
			e = ne
		}
	}

	down := make([]int64, n1)
	for i := len(order) - 1; i >= 0; i-- {
		u := int(order[i])
		best := vert[u]
		pu := int(anc[u])
		for e := head[u]; e != -1; {
			ei := int(e)
			v := int(to[ei])
			ne := nxt[ei]
			if v != pu {
				cand := wa[ei] + wb[ei] + down[v]
				if cand < best {
					best = cand
				}
			}
			e = ne
		}
		down[u] = best
	}

	up := make([]int64, n1)
	up[1] = INF

	for _, uu := range order {
		u := int(uu)
		best1, best2 := INF, INF
		from1 := 0
		pu := int(anc[u])

		for e := head[u]; e != -1; {
			ei := int(e)
			v := int(to[ei])
			ne := nxt[ei]
			val := wa[ei] + wb[ei]
			if v == pu {
				val += up[u]
			} else {
				val += down[v]
			}
			if val < best1 {
				best2 = best1
				best1 = val
				from1 = v
			} else if val < best2 {
				best2 = val
			}
			e = ne
		}

		direct := vert[u]
		best := direct
		if best1 < best {
			best = best1
		}
		vert[u] = best

		for e := head[u]; e != -1; {
			ei := int(e)
			v := int(to[ei])
			ne := nxt[ei]
			if v != pu {
				msg := direct
				if from1 != v {
					if best1 < msg {
						msg = best1
					}
				} else {
					if best2 < msg {
						msg = best2
					}
				}
				up[v] = msg
			}
			e = ne
		}
	}

	mats := make([]Mat, lg*n1)
	mats[1] = idMat
	for v := 2; v <= n; v++ {
		ei := int(parEdge[v])
		a := wa[ei]
		b := wb[ei]
		dv := vert[v]
		mats[v] = Mat{a, dv + b, dv + a, b}
	}

	for k := 1; k < lg; k++ {
		prevBase := (k - 1) * n1
		curBase := k * n1
		for v := 1; v <= n; v++ {
			mid := int(anc[prevBase+v])
			if mid != 0 {
				anc[curBase+v] = anc[prevBase+mid]
				mats[curBase+v] = mul(mats[prevBase+v], mats[prevBase+mid])
			} else {
				anc[curBase+v] = 0
				mats[curBase+v] = mats[prevBase+v]
			}
		}
	}

	head = nil
	to = nil
	nxt = nil
	wa = nil
	wb = nil
	parEdge = nil
	stack = nil
	order = nil
	down = nil
	up = nil
	runtime.GC()

	q := fs.NextInt()

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	var tmp [32]byte

	for i := 0; i < q; i++ {
		u := fs.NextInt()
		v := fs.NextInt()

		x := (u + 1) >> 1
		y := (v + 1) >> 1
		sx := 1 - (u & 1)
		sy := 1 - (v & 1)

		l := lca(x, y, n1, lg, depth, anc)
		mx := prodUp(x, l, n1, depth, anc, mats)
		my := prodUp(y, l, n1, depth, anc, mats)
		vl := Mat{0, vert[l], vert[l], 0}
		ansMat := mul(mul(mx, vl), trans(my))

		var ans int64
		if sx == 0 {
			if sy == 0 {
				ans = ansMat.a00
			} else {
				ans = ansMat.a01
			}
		} else {
			if sy == 0 {
				ans = ansMat.a10
			} else {
				ans = ansMat.a11
			}
		}

		b := strconv.AppendInt(tmp[:0], ans, 10)
		out.Write(b)
		out.WriteByte('\n')
	}

	out.Flush()
}