← Home
For problem statement at 0-999/800-899/890-899/896/problemC.txt this is a correct solution, but verifier at 0-999/800-899/890-899/896/verifierC.go ends with Passed 100 tests can you fix the verifier? package main

import (
	"io"
	"os"
	"sort"
	"strconv"
)

type Pair struct {
	v int64
	c int
}

var (
	n, m     int
	vmax     int64
	probSeed int64
	root     int

	L, R          []int
	Left, Right   []int
	Val           []int64
	Pri           []uint32
	tot           int
	prioSeed uint64 = 88172645463393265

	pairs []Pair
)

func nextPri() uint32 {
	prioSeed ^= prioSeed << 7
	prioSeed ^= prioSeed >> 9
	return uint32(prioSeed)
}

func newNode(l, r int, v int64) int {
	tot++
	L[tot] = l
	R[tot] = r
	Left[tot] = 0
	Right[tot] = 0
	Val[tot] = v
	Pri[tot] = nextPri()
	return tot
}

func rnd() int64 {
	ret := probSeed
	probSeed = (probSeed*7 + 13) % 1000000007
	return ret
}

func merge(a, b int) int {
	if a == 0 {
		return b
	}
	if b == 0 {
		return a
	}
	if Pri[a] < Pri[b] {
		Right[a] = merge(Right[a], b)
		return a
	}
	Left[b] = merge(a, Left[b])
	return b
}

func splitKey(t, key int) (int, int) {
	if t == 0 {
		return 0, 0
	}
	if L[t] <= key {
		x, y := splitKey(Right[t], key)
		Right[t] = x
		return t, y
	}
	x, y := splitKey(Left[t], key)
	Left[t] = y
	return x, t
}

func insert(t, x int) int {
	a, b := splitKey(t, L[x]-1)
	return merge(merge(a, x), b)
}

func erase(t, key int) int {
	if t == 0 {
		return 0
	}
	if key < L[t] {
		Left[t] = erase(Left[t], key)
		return t
	}
	if key > L[t] {
		Right[t] = erase(Right[t], key)
		return t
	}
	return merge(Left[t], Right[t])
}

func find(t, key int) int {
	for t != 0 {
		if key < L[t] {
			t = Left[t]
		} else if key > L[t] {
			t = Right[t]
		} else {
			return t
		}
	}
	return 0
}

func pred(t, key int) int {
	res := 0
	for t != 0 {
		if L[t] <= key {
			res = t
			t = Right[t]
		} else {
			t = Left[t]
		}
	}
	return res
}

func succ(t, key int) int {
	res := 0
	for t != 0 {
		if L[t] > key {
			res = t
			t = Left[t]
		} else {
			t = Right[t]
		}
	}
	return res
}

func splitPos(pos int) {
	if pos <= 1 || pos > n {
		return
	}
	p := pred(root, pos)
	if p == 0 || L[p] == pos || pos > R[p] {
		return
	}
	l, r, v := L[p], R[p], Val[p]
	root = erase(root, l)
	root = insert(root, newNode(l, pos-1, v))
	root = insert(root, newNode(pos, r, v))
}

func extractRange(l, r int) (int, int, int) {
	splitPos(l)
	splitPos(r + 1)
	t, c := splitKey(root, r)
	a, b := splitKey(t, l-1)
	return a, b, c
}

func mergeAtKey(key int) {
	cur := find(root, key)
	if cur == 0 {
		return
	}
	v := Val[cur]
	nl, nr := L[cur], R[cur]
	merged := false

	p := pred(root, key-1)
	if p != 0 && Val[p] == v {
		nl = L[p]
		root = erase(root, L[p])
		merged = true
	}

	s := succ(root, key)
	if s != 0 && Val[s] == v {
		nr = R[s]
		root = erase(root, L[s])
		merged = true
	}

	if merged {
		root = erase(root, key)
		root = insert(root, newNode(nl, nr, v))
	}
}

func addAll(t int, x int64) {
	if t == 0 {
		return
	}
	Val[t] += x
	addAll(Left[t], x)
	addAll(Right[t], x)
}

func collectPairs(t int) {
	if t == 0 {
		return
	}
	collectPairs(Left[t])
	pairs = append(pairs, Pair{Val[t], R[t] - L[t] + 1})
	collectPairs(Right[t])
}

func powMod(a, e, mod int64) int64 {
	if mod == 1 {
		return 0
	}
	a %= mod
	res := int64(1 % mod)
	for e > 0 {
		if e&1 == 1 {
			res = res * a % mod
		}
		a = a * a % mod
		e >>= 1
	}
	return res
}

func sumTree(t int, e, mod int64) int64 {
	if t == 0 {
		return 0
	}
	res := sumTree(Left[t], e, mod)
	res += sumTree(Right[t], e, mod)
	res %= mod
	res += int64(R[t]-L[t]+1) * powMod(Val[t], e, mod) % mod
	if res >= mod {
		res %= mod
	}
	return res
}

func rangeAdd(l, r int, x int64) {
	a, b, c := extractRange(l, r)
	addAll(b, x)
	root = merge(merge(a, b), c)
	mergeAtKey(l)
	if r+1 <= n {
		mergeAtKey(r + 1)
	}
}

func rangeAssign(l, r int, x int64) {
	a, _, c := extractRange(l, r)
	mid := newNode(l, r, x)
	root = merge(merge(a, mid), c)
	mergeAtKey(l)
	if r+1 <= n {
		mergeAtKey(r + 1)
	}
}

func rangeKth(l, r, k int) int64 {
	a, b, c := extractRange(l, r)
	pairs = pairs[:0]
	collectPairs(b)
	if len(pairs) > 1 {
		sort.Slice(pairs, func(i, j int) bool {
			return pairs[i].v < pairs[j].v
		})
	}
	ans := int64(0)
	for i := 0; i < len(pairs); i++ {
		if k <= pairs[i].c {
			ans = pairs[i].v
			break
		}
		k -= pairs[i].c
	}
	root = merge(merge(a, b), c)
	mergeAtKey(l)
	if r+1 <= n {
		mergeAtKey(r + 1)
	}
	return ans
}

func rangeSum(l, r int, e, mod int64) int64 {
	a, b, c := extractRange(l, r)
	ans := int64(0)
	if mod != 1 {
		ans = sumTree(b, e, mod) % mod
	}
	root = merge(merge(a, b), c)
	mergeAtKey(l)
	if r+1 <= n {
		mergeAtKey(r + 1)
	}
	return ans
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int64 {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		var x int64
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			x = x*10 + int64(data[idx]-'0')
			idx++
		}
		return x
	}

	n = int(nextInt())
	m = int(nextInt())
	probSeed = nextInt()
	vmax = nextInt()

	maxNodes := n + m*10 + 100
	L = make([]int, maxNodes)
	R = make([]int, maxNodes)
	Left = make([]int, maxNodes)
	Right = make([]int, maxNodes)
	Val = make([]int64, maxNodes)
	Pri = make([]uint32, maxNodes)
	pairs = make([]Pair, 0, 64)

	start := 1
	cur := rnd()%vmax + 1
	for i := 2; i <= n; i++ {
		x := rnd()%vmax + 1
		if x != cur {
			root = merge(root, newNode(start, i-1, cur))
			start = i
			cur = x
		}
	}
	root = merge(root, newNode(start, n, cur))

	out := make([]byte, 0, m*12)

	for i := 0; i < m; i++ {
		op := int(rnd()%4) + 1
		l := int(rnd()%int64(n)) + 1
		r := int(rnd()%int64(n)) + 1
		if l > r {
			l, r = r, l
		}
		var x int64
		if op == 3 {
			x = rnd()%int64(r-l+1) + 1
		} else {
			x = rnd()%vmax + 1
		}

		if op == 1 {
			rangeAdd(l, r, x)
		} else if op == 2 {
			rangeAssign(l, r, x)
		} else if op == 3 {
			ans := rangeKth(l, r, int(x))
			out = strconv.AppendInt(out, ans, 10)
			out = append(out, '\n')
		} else {
			y := rnd()%vmax + 1
			ans := rangeSum(l, r, x, y)
			out = strconv.AppendInt(out, ans, 10)
			out = append(out, '\n')
		}
	}

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