← Home
For problem statement at 0-999/800-899/810-819/811/problemE.txt this is a correct solution, but verifier at 0-999/800-899/810-819/811/verifierE.go ends with All tests passed can you fix the verifier? package main

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

type FastScanner struct {
	data []byte
	idx  int
}

func (fs *FastScanner) NextInt() int {
	n := len(fs.data)
	for fs.idx < n && (fs.data[fs.idx] < '0' || fs.data[fs.idx] > '9') {
		fs.idx++
	}
	val := 0
	for fs.idx < n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		val = val*10 + int(c-'0')
		fs.idx++
	}
	return val
}

type Node struct {
	cnt int32
	lid [10]int32
	rid [10]int32
	lv  [10]int32
	rv  [10]int32
}

var N int

func find(parent *[40]int, x int) int {
	for parent[x] != x {
		parent[x] = parent[parent[x]]
		x = parent[x]
	}
	return x
}

func addMap(mp *[20]int, label int32, parent *[40]int, d *int) int {
	idx := int(label)
	if mp[idx] == -1 {
		cur := *d
		mp[idx] = cur
		parent[cur] = cur
		*d = cur + 1
	}
	return mp[idx]
}

func merge(a, b Node) Node {
	var res Node
	res.cnt = a.cnt + b.cnt
	res.lv = a.lv
	res.rv = b.rv

	var mx, my [20]int
	for i := 0; i < 20; i++ {
		mx[i] = -1
		my[i] = -1
	}

	var parent [40]int
	d := 0
	for i := 0; i < N; i++ {
		addMap(&mx, a.lid[i], &parent, &d)
		addMap(&mx, a.rid[i], &parent, &d)
		addMap(&my, b.lid[i], &parent, &d)
		addMap(&my, b.rid[i], &parent, &d)
	}

	for i := 0; i < N; i++ {
		if a.rv[i] == b.lv[i] {
			x := mx[int(a.rid[i])]
			y := my[int(b.lid[i])]
			rx := find(&parent, x)
			ry := find(&parent, y)
			if rx != ry {
				parent[rx] = ry
				res.cnt--
			}
		}
	}

	var rep [40]int
	for i := 0; i < 40; i++ {
		rep[i] = -1
	}
	next := 0

	for i := 0; i < N; i++ {
		rt := find(&parent, mx[int(a.lid[i])])
		if rep[rt] == -1 {
			rep[rt] = next
			next++
		}
		res.lid[i] = int32(rep[rt])
	}
	for i := 0; i < N; i++ {
		rt := find(&parent, my[int(b.rid[i])])
		if rep[rt] == -1 {
			rep[rt] = next
			next++
		}
		res.rid[i] = int32(rep[rt])
	}

	return res
}

func query(tree []Node, size, l, r int) Node {
	l += size
	r += size + 1

	var left, right Node
	left.cnt = -1
	right.cnt = -1

	for l < r {
		if l&1 == 1 {
			if left.cnt == -1 {
				left = tree[l]
			} else {
				left = merge(left, tree[l])
			}
			l++
		}
		if r&1 == 1 {
			r--
			if right.cnt == -1 {
				right = tree[r]
			} else {
				right = merge(tree[r], right)
			}
		}
		l >>= 1
		r >>= 1
	}

	if left.cnt == -1 {
		return right
	}
	if right.cnt == -1 {
		return left
	}
	return merge(left, right)
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	fs := FastScanner{data: data}

	n := fs.NextInt()
	m := fs.NextInt()
	q := fs.NextInt()
	N = n

	rows := make([][]int32, n)
	for i := 0; i < n; i++ {
		rows[i] = make([]int32, m)
		for j := 0; j < m; j++ {
			rows[i][j] = int32(fs.NextInt())
		}
	}

	size := 1
	for size < m {
		size <<= 1
	}
	tree := make([]Node, size<<1)

	for i := 0; i < size; i++ {
		tree[size+i].cnt = -1
	}

	for col := 0; col < m; col++ {
		var node Node
		node.cnt = 1
		for r := 0; r < n; r++ {
			v := rows[r][col]
			node.lv[r] = v
			node.rv[r] = v
		}
		node.lid[0] = 0
		node.rid[0] = 0
		var lbl int32 = 0
		for r := 1; r < n; r++ {
			if node.lv[r] == node.lv[r-1] {
				node.lid[r] = lbl
			} else {
				lbl++
				node.lid[r] = lbl
				node.cnt++
			}
			node.rid[r] = node.lid[r]
		}
		tree[size+col] = node
	}

	for i := size - 1; i >= 1; i-- {
		left := tree[i<<1]
		right := tree[i<<1|1]
		if left.cnt == -1 {
			tree[i] = right
		} else if right.cnt == -1 {
			tree[i] = left
		} else {
			tree[i] = merge(left, right)
		}
	}

	out := make([]byte, 0, q*8)
	for i := 0; i < q; i++ {
		l := fs.NextInt() - 1
		r := fs.NextInt() - 1
		ans := query(tree, size, l, r)
		out = strconv.AppendInt(out, int64(ans.cnt), 10)
		out = append(out, '\n')
	}

	os.Stdout.Write(out)
}