← Home
For problem statement at 0-999/600-699/670-679/678/problemF.txt this is a correct solution, but verifier at 0-999/600-699/670-679/678/verifierF.go ends with case 1 failed:
expected:
EMPTY SET
EMPTY SET
EMPTY SET
EMPTY SET
EMPTY SET
EMPTY SET
 got:
EMPTY SET
EMPTY SET
EMPTY SET
EMPTY SET
EMPTY SET
-12

exit status 1 can you fix the verifier? package main

import (
	"io"
	"math/bits"
	"os"
	"sort"
	"strconv"
)

type Edge struct {
	line int32
	next int32
}

type Change struct {
	node int32
	prev int32
}

const NEG int64 = -1 << 62

var (
	n         int
	m         int
	qCount    int
	slope     []int64
	intercept []int64
	removeAt  []int32
	queryIdxs []int32
	xs        []int64
	headT     []int32
	edgesT    []Edge
	lcTree    []int32
	changes   []Change
	out       []byte
)

func lowerBoundInt(a []int, x int) int {
	l, r := 0, len(a)
	for l < r {
		mid := (l + r) >> 1
		if a[mid] < x {
			l = mid + 1
		} else {
			r = mid
		}
	}
	return l
}

func upperBoundInt(a []int, x int) int {
	l, r := 0, len(a)
	for l < r {
		mid := (l + r) >> 1
		if a[mid] <= x {
			l = mid + 1
		} else {
			r = mid
		}
	}
	return l
}

func lowerBound64(a []int64, x int64) int32 {
	l, r := 0, len(a)
	for l < r {
		mid := (l + r) >> 1
		if a[mid] < x {
			l = mid + 1
		} else {
			r = mid
		}
	}
	return int32(l)
}

func insertLine(id int32) {
	node, l, r := 1, 0, m-1
	mi, bi := slope[int(id)], intercept[int(id)]
	for {
		cur := lcTree[node]
		if cur == 0 {
			changes = append(changes, Change{int32(node), 0})
			lcTree[node] = id
			return
		}

		ci := int(cur)
		mc, bc := slope[ci], intercept[ci]
		mid := (l + r) >> 1
		xm := xs[mid]

		if mi*xm+bi > mc*xm+bc {
			changes = append(changes, Change{int32(node), cur})
			lcTree[node] = id
			id = cur
			tmpm, tmpb := mi, bi
			mi, bi = mc, bc
			mc, bc = tmpm, tmpb
		}

		if l == r {
			return
		}

		xl := xs[l]
		if mi*xl+bi > mc*xl+bc {
			node <<= 1
			r = mid
			continue
		}

		xr := xs[r]
		if mi*xr+bi > mc*xr+bc {
			node = node<<1 | 1
			l = mid + 1
			continue
		}

		return
	}
}

func queryVal(idx int32) int64 {
	x := xs[int(idx)]
	res := NEG
	node, l, r := 1, 0, m-1
	for {
		cur := lcTree[node]
		if cur != 0 {
			ci := int(cur)
			v := slope[ci]*x + intercept[ci]
			if v > res {
				res = v
			}
		}
		if l == r {
			break
		}
		mid := (l + r) >> 1
		if int(idx) <= mid {
			node <<= 1
			r = mid
		} else {
			node = node<<1 | 1
			l = mid + 1
		}
	}
	return res
}

func dfs(node, l, r int) {
	if l > qCount {
		return
	}

	cp := len(changes)

	for e := headT[node]; e != 0; e = edgesT[e].next {
		insertLine(edgesT[e].line)
	}

	if l == r {
		res := queryVal(queryIdxs[l-1])
		if res == NEG {
			out = append(out, "EMPTY SET\n"...)
		} else {
			out = strconv.AppendInt(out, res, 10)
			out = append(out, '\n')
		}
	} else {
		mid := (l + r) >> 1
		dfs(node<<1, l, mid)
		dfs(node<<1|1, mid+1, r)
	}

	for len(changes) > cp {
		c := changes[len(changes)-1]
		lcTree[int(c.node)] = c.prev
		changes = changes[:len(changes)-1]
	}
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	p := 0
	nextInt64 := func() int64 {
		for p < len(data) && data[p] <= ' ' {
			p++
		}
		sign := int64(1)
		if data[p] == '-' {
			sign = -1
			p++
		}
		var v int64
		for p < len(data) {
			c := data[p]
			if c < '0' || c > '9' {
				break
			}
			v = v*10 + int64(c-'0')
			p++
		}
		return sign * v
	}

	n = int(nextInt64())
	slope = make([]int64, n+1)
	intercept = make([]int64, n+1)
	removeAt = make([]int32, n+1)

	addIdx := make([]int, 0)
	queryTimes := make([]int, 0)
	queryVals := make([]int64, 0)
	xsAll := make([]int64, 0)

	for i := 1; i <= n; i++ {
		t := int(nextInt64())
		if t == 1 {
			a := nextInt64()
			b := nextInt64()
			slope[i] = a
			intercept[i] = b
			removeAt[i] = int32(n + 1)
			addIdx = append(addIdx, i)
		} else if t == 2 {
			idx := int(nextInt64())
			removeAt[idx] = int32(i)
		} else {
			q := nextInt64()
			queryTimes = append(queryTimes, i)
			queryVals = append(queryVals, q)
			xsAll = append(xsAll, q)
		}
	}

	qCount = len(queryTimes)
	if qCount == 0 {
		return
	}

	sort.Slice(xsAll, func(i, j int) bool { return xsAll[i] < xsAll[j] })
	k := 0
	for _, v := range xsAll {
		if k == 0 || xsAll[k-1] != v {
			xsAll[k] = v
			k++
		}
	}
	xs = xsAll[:k]
	m = len(xs)

	queryIdxs = make([]int32, qCount)
	for i, v := range queryVals {
		queryIdxs[i] = lowerBound64(xs, v)
	}

	sizeT := 1
	for sizeT < qCount {
		sizeT <<= 1
	}

	countEdges := 0
	for _, idx := range addIdx {
		l := idx
		r := int(removeAt[idx]) - 1
		li := lowerBoundInt(queryTimes, l)
		ri := upperBoundInt(queryTimes, r) - 1
		if li > ri {
			continue
		}
		L := li + 1 + sizeT - 1
		R := ri + 1 + sizeT - 1
		for L <= R {
			if L&1 == 1 {
				countEdges++
				L++
			}
			if R&1 == 0 {
				countEdges++
				R--
			}
			L >>= 1
			R >>= 1
		}
	}

	headT = make([]int32, 2*sizeT)
	edgesT = make([]Edge, 1, countEdges+1)

	for _, idx := range addIdx {
		l := idx
		r := int(removeAt[idx]) - 1
		li := lowerBoundInt(queryTimes, l)
		ri := upperBoundInt(queryTimes, r) - 1
		if li > ri {
			continue
		}
		L := li + 1 + sizeT - 1
		R := ri + 1 + sizeT - 1
		for L <= R {
			if L&1 == 1 {
				edgesT = append(edgesT, Edge{int32(idx), headT[L]})
				headT[L] = int32(len(edgesT) - 1)
				L++
			}
			if R&1 == 0 {
				edgesT = append(edgesT, Edge{int32(idx), headT[R]})
				headT[R] = int32(len(edgesT) - 1)
				R--
			}
			L >>= 1
			R >>= 1
		}
	}

	lcTree = make([]int32, m*4+5)
	changes = make([]Change, 0, len(addIdx)*(bits.Len(uint(m))+1)+1)
	out = make([]byte, 0, qCount*24)

	dfs(1, 1, sizeT)

	_, _ = os.Stdout.Write(out)
}