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)
}