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

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
)

const MaxX int64 = 1000000000000000000

type Key struct {
	id int
	x  int64
}

type Item struct {
	id int
	va int64
	vc int64
}

type Pair struct {
	item Item
	vx   int64
}

var (
	in    = bufio.NewReaderSize(os.Stdin, 1<<20)
	out   = bufio.NewWriterSize(os.Stdout, 1<<20)
	rng   = rand.New(rand.NewSource(1))
	n     int
	L     int64
	B     int64
	cache map[Key]int64
	ansL  []int64
	ansR  []int64
)

func query(id int, x int64) int64 {
	k := Key{id: id, x: x}
	if v, ok := cache[k]; ok {
		return v
	}
	fmt.Fprintf(out, "? %d %d\n", id+1, x)
	out.Flush()
	var v int64
	if _, err := fmt.Fscan(in, &v); err != nil {
		os.Exit(0)
	}
	if v < 0 {
		os.Exit(0)
	}
	cache[k] = v
	return v
}

func findPos(id int, lo int64, hi int64, va int64, target int64) int64 {
	for hi-lo > 1 {
		mid := lo + (hi-lo)/2
		if query(id, mid)-va >= target {
			hi = mid
		} else {
			lo = mid
		}
	}
	return hi
}

func selectX(items []Item, A int64, C int64, m int) int64 {
	target := int64(m) * B
	cur := make([]Item, len(items))
	copy(cur, items)
	lo, hi := A, C
	need := m
	for {
		piv := cur[rng.Intn(len(cur))]
		x := findPos(piv.id, lo, hi, piv.va, target)

		low := make([]Item, 0, len(cur))
		eq := make([]Item, 0, len(cur))
		high := make([]Item, 0, len(cur))

		for _, it := range cur {
			vx := query(it.id, x)
			d := vx - it.va
			if d < target {
				high = append(high, it)
			} else if d > target {
				low = append(low, it)
			} else {
				if x == lo+1 {
					eq = append(eq, it)
				} else {
					vprev := query(it.id, x-1)
					if vprev-it.va >= target {
						low = append(low, it)
					} else {
						eq = append(eq, it)
					}
				}
			}
		}

		if len(low) < need && need <= len(low)+len(eq) {
			return x
		}
		if need <= len(low) {
			cur = low
			hi = x - 1
		} else {
			need -= len(low) + len(eq)
			cur = high
			lo = x
		}
	}
}

func solve(items []Item, A int64, C int64) {
	s := len(items)
	if s == 1 {
		ansL[items[0].id] = A
		ansR[items[0].id] = C
		return
	}

	m := s / 2
	x := selectX(items, A, C, m)
	target := int64(m) * B

	gt := make([]Pair, 0, s)
	eq := make([]Pair, 0, s)
	lt := make([]Pair, 0, s)

	for _, it := range items {
		vx := query(it.id, x)
		p := Pair{item: it, vx: vx}
		d := vx - it.va
		if d > target {
			gt = append(gt, p)
		} else if d == target {
			eq = append(eq, p)
		} else {
			lt = append(lt, p)
		}
	}

	left := make([]Item, 0, m)
	right := make([]Item, 0, s-m)

	for _, p := range gt {
		left = append(left, Item{id: p.item.id, va: p.item.va, vc: p.vx})
	}

	needEq := m - len(left)
	for i, p := range eq {
		if i < needEq {
			left = append(left, Item{id: p.item.id, va: p.item.va, vc: p.vx})
		} else {
			right = append(right, Item{id: p.item.id, va: p.vx, vc: p.item.vc})
		}
	}

	for _, p := range lt {
		right = append(right, Item{id: p.item.id, va: p.vx, vc: p.item.vc})
	}

	solve(left, A, x)
	solve(right, x, C)
}

func main() {
	defer out.Flush()

	if _, err := fmt.Fscan(in, &n, &L); err != nil {
		return
	}
	B = L / int64(n)

	cache = make(map[Key]int64, 1<<20)
	ansL = make([]int64, n)
	ansR = make([]int64, n)

	items := make([]Item, n)
	for i := 0; i < n; i++ {
		cache[Key{id: i, x: 0}] = 0
		cache[Key{id: i, x: MaxX}] = L
		items[i] = Item{id: i, va: 0, vc: L}
	}

	solve(items, 0, MaxX)

	fmt.Fprintln(out, "!")
	for i := 0; i < n; i++ {
		fmt.Fprintln(out, ansL[i], ansR[i])
	}
}