← Home
For problem statement at 1000-1999/1400-1499/1470-1479/1479/problemD.txt this is a correct solution, but verifier at 1000-1999/1400-1499/1470-1479/1479/verifierD.go ends with All 100 tests passed can you fix the verifier? package main

import (
	"io"
	"os"
	"strconv"
	"time"
)

const LOG = 20

type Node struct {
	l int32
	r int32
	h uint64
}

var data []byte
var ptr int
var nodes []Node
var tot int32

func nextInt() int {
	n := len(data)
	for ptr < n && (data[ptr] < '0' || data[ptr] > '9') {
		ptr++
	}
	v := 0
	for ptr < n && data[ptr] >= '0' && data[ptr] <= '9' {
		v = v*10 + int(data[ptr]-'0')
		ptr++
	}
	return v
}

func splitmix64(x uint64) uint64 {
	x += 0x9e3779b97f4a7c15
	x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9
	x = (x ^ (x >> 27)) * 0x94d049bb133111eb
	return x ^ (x >> 31)
}

func update(prev int32, l, r, pos int, hv uint64) int32 {
	idx := tot
	tot++
	nodes[idx] = nodes[prev]
	if l == r {
		nodes[idx].h ^= hv
		return idx
	}
	mid := (l + r) >> 1
	if pos <= mid {
		nodes[idx].l = update(nodes[prev].l, l, mid, pos, hv)
	} else {
		nodes[idx].r = update(nodes[prev].r, mid+1, r, pos, hv)
	}
	nodes[idx].h = nodes[nodes[idx].l].h ^ nodes[nodes[idx].r].h
	return idx
}

func findAny(a, b, c, d int32, l, r, ql, qr int) int {
	if qr < l || r < ql {
		return -1
	}
	h := nodes[a].h ^ nodes[b].h ^ nodes[c].h ^ nodes[d].h
	if h == 0 {
		return -1
	}
	if l == r {
		return l
	}
	mid := (l + r) >> 1
	if ql <= mid {
		res := findAny(nodes[a].l, nodes[b].l, nodes[c].l, nodes[d].l, l, mid, ql, qr)
		if res != -1 {
			return res
		}
	}
	if qr > mid {
		res := findAny(nodes[a].r, nodes[b].r, nodes[c].r, nodes[d].r, mid+1, r, ql, qr)
		if res != -1 {
			return res
		}
	}
	return -1
}

func lca(u, v int, up []int32, depth []int, stride int) int {
	if depth[u] < depth[v] {
		u, v = v, u
	}
	d := depth[u] - depth[v]
	k := 0
	for d > 0 {
		if d&1 != 0 {
			u = int(up[k*stride+u])
		}
		d >>= 1
		k++
	}
	if u == v {
		return u
	}
	for k = LOG - 1; k >= 0; k-- {
		pu := int(up[k*stride+u])
		pv := int(up[k*stride+v])
		if pu != pv {
			u = pu
			v = pv
		}
	}
	return int(up[u])
}

func main() {
	data, _ = io.ReadAll(os.Stdin)

	n := nextInt()
	q := nextInt()

	val := make([]int, n+1)
	for i := 1; i <= n; i++ {
		val[i] = nextInt()
	}

	head := make([]int32, n+1)
	for i := 0; i <= n; i++ {
		head[i] = -1
	}
	to := make([]int32, 2*(n-1))
	nxt := make([]int32, 2*(n-1))
	var ec int32
	for i := 0; i < n-1; i++ {
		x := nextInt()
		y := nextInt()
		to[ec] = int32(y)
		nxt[ec] = head[x]
		head[x] = ec
		ec++
		to[ec] = int32(x)
		nxt[ec] = head[y]
		head[y] = ec
		ec++
	}

	hashv := make([]uint64, n+1)
	seed := uint64(time.Now().UnixNano())
	for i := 1; i <= n; i++ {
		h := splitmix64(seed + uint64(i))
		if h == 0 {
			h = 1
		}
		hashv[i] = h
	}

	maxNodes := (n + 5) * 21
	nodes = make([]Node, maxNodes)
	tot = 1

	roots := make([]int32, n+1)
	depth := make([]int, n+1)
	stride := n + 1
	up := make([]int32, LOG*stride)

	roots[1] = update(0, 1, n, val[1], hashv[val[1]])

	stack := make([]int, 0, n)
	stack = append(stack, 1)
	for len(stack) > 0 {
		v := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		for e := head[v]; e != -1; e = nxt[e] {
			u := int(to[e])
			if u == int(up[v]) {
				continue
			}
			up[u] = int32(v)
			depth[u] = depth[v] + 1
			roots[u] = update(roots[v], 1, n, val[u], hashv[val[u]])
			stack = append(stack, u)
		}
	}

	for k := 1; k < LOG; k++ {
		base := k * stride
		prev := (k - 1) * stride
		for v := 1; v <= n; v++ {
			p := up[prev+v]
			if p != 0 {
				up[base+v] = up[prev+int(p)]
			}
		}
	}

	out := make([]byte, 0, q*8)
	for i := 0; i < q; i++ {
		u := nextInt()
		v := nextInt()
		l := nextInt()
		r := nextInt()
		w := lca(u, v, up, depth, stride)
		pw := int(up[w])
		ans := findAny(roots[u], roots[v], roots[w], roots[pw], 1, n, l, r)
		out = strconv.AppendInt(out, int64(ans), 10)
		out = append(out, '\n')
	}

	os.Stdout.Write(out)
}