← Home
For problem statement at 1000-1999/1200-1299/1260-1269/1261/problemF.txt this is a correct solution, but verifier at 1000-1999/1200-1299/1260-1269/1261/verifierF.go ends with test 1 failed
input:
2
405980 412713
165866 171978
4
191580 191740
296388 345705
404518 474072
170245 265715

expected: 414768047
got: 927747425

exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
)

var MOD int64 = 998244353
var INV2 int64 = 499122177

func power(base, exp int64) int64 {
	res := int64(1)
	base %= MOD
	for exp > 0 {
		if exp%2 == 1 {
			res = (res * base) % MOD
		}
		base = (base * base) % MOD
		exp /= 2
	}
	return res
}

type Node struct {
	id     int32
	isFull bool
	left   *Node
	right  *Node
}

var fullNode = &Node{id: 1, isFull: true}
var nextNodeId int32 = 2

type nodeKey struct {
	left, right int32
}

var internMap = make(map[nodeKey]*Node)
var memoXor = make(map[nodeKey]*Node)
var memoMerge = make(map[nodeKey]*Node)

func getNode(left, right *Node) *Node {
	if left == fullNode && right == fullNode {
		return fullNode
	}
	if left == nil && right == nil {
		return nil
	}
	var lid, rid int32 = 0, 0
	if left != nil {
		lid = left.id
	}
	if right != nil {
		rid = right.id
	}
	k := nodeKey{lid, rid}
	if n, ok := internMap[k]; ok {
		return n
	}
	n := &Node{id: nextNodeId, isFull: false, left: left, right: right}
	nextNodeId++
	internMap[k] = n
	return n
}

func merge(a, b *Node) *Node {
	if a == nil {
		return b
	}
	if b == nil {
		return a
	}
	if a == b {
		return a
	}
	if a.isFull || b.isFull {
		return fullNode
	}
	lid, rid := a.id, b.id
	if lid > rid {
		lid, rid = rid, lid
	}
	k := nodeKey{lid, rid}

	if res, ok := memoMerge[k]; ok {
		return res
	}

	left := merge(a.left, b.left)
	right := merge(a.right, b.right)

	res := getNode(left, right)
	memoMerge[k] = res
	return res
}

func xorTrie(a, b *Node) *Node {
	if a == nil || b == nil {
		return nil
	}
	if a.isFull || b.isFull {
		return fullNode
	}

	lid, rid := a.id, b.id
	if lid > rid {
		lid, rid = rid, lid
	}
	k := nodeKey{lid, rid}

	if res, ok := memoXor[k]; ok {
		return res
	}

	ll := xorTrie(a.left, b.left)
	rr := xorTrie(a.right, b.right)
	lr := xorTrie(a.left, b.right)
	rl := xorTrie(a.right, b.left)

	left := merge(ll, rr)
	right := merge(lr, rl)

	res := getNode(left, right)
	memoXor[k] = res
	return res
}

func build(d int, L, R, valL, valR int64) *Node {
	if L > valR || R < valL {
		return nil
	}
	if L <= valL && valR <= R {
		return fullNode
	}
	mid := valL + (valR-valL)/2
	left := build(d-1, L, R, valL, mid)
	right := build(d-1, L, R, mid+1, valR)
	return getNode(left, right)
}

type sumKey struct {
	id int32
	d  int32
}

var memoSum = make(map[sumKey]struct{ count, sum int64 })

func compute(node *Node, d int) (int64, int64) {
	if node == nil {
		return 0, 0
	}
	if node == fullNode {
		cnt := power(2, int64(d+1))
		sum := (cnt * (cnt - 1 + MOD)) % MOD
		sum = (sum * INV2) % MOD
		return cnt, sum
	}
	k := sumKey{node.id, int32(d)}
	if res, ok := memoSum[k]; ok {
		return res.count, res.sum
	}

	cntL, sumL := compute(node.left, d-1)
	cntR, sumR := compute(node.right, d-1)

	cnt := (cntL + cntR) % MOD

	bitVal := power(2, int64(d))
	sumR_add := (cntR * bitVal) % MOD
	sumR_total := (sumR + sumR_add) % MOD

	sum := (sumL + sumR_total) % MOD

	memoSum[k] = struct{ count, sum int64 }{cnt, sum}
	return cnt, sum
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	var nA int
	if _, err := fmt.Fscan(reader, &nA); err != nil {
		return
	}

	var rootA *Node
	for i := 0; i < nA; i++ {
		var l, r int64
		fmt.Fscan(reader, &l, &r)
		node := build(59, l, r, 0, (int64(1)<<60)-1)
		rootA = merge(rootA, node)
	}

	var nB int
	fmt.Fscan(reader, &nB)

	var rootB *Node
	for i := 0; i < nB; i++ {
		var l, r int64
		fmt.Fscan(reader, &l, &r)
		node := build(59, l, r, 0, (int64(1)<<60)-1)
		rootB = merge(rootB, node)
	}

	rootC := xorTrie(rootA, rootB)
	_, sumC := compute(rootC, 59)
	fmt.Println(sumC)
}