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