← Home
For problem statement at 0-999/0-99/40-49/40/problemE.txt this is a correct solution, but verifier at 0-999/0-99/40-49/40/verifierE.go ends with All 100 tests passed can you fix the verifier? package main

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

type DSU struct {
	p, r []int
}

func NewDSU(n int) *DSU {
	p := make([]int, n)
	r := make([]int, n)
	for i := 0; i < n; i++ {
		p[i] = i
	}
	return &DSU{p: p, r: r}
}
func (d *DSU) Find(x int) int {
	if d.p[x] != x {
		d.p[x] = d.Find(d.p[x])
	}
	return d.p[x]
}
func (d *DSU) Union(a, b int) {
	ra := d.Find(a)
	rb := d.Find(b)
	if ra == rb {
		return
	}
	if d.r[ra] < d.r[rb] {
		ra, rb = rb, ra
	}
	d.p[rb] = ra
	if d.r[ra] == d.r[rb] {
		d.r[ra]++
	}
}

func powMod2(exp int64, mod int64) int64 {
	if mod == 1 {
		return 0
	}
	res := int64(1 % mod)
	base := int64(2 % mod)
	for exp > 0 {
		if exp&1 == 1 {
			res = (res * base) % mod
		}
		base = (base * base) % mod
		exp >>= 1
	}
	return res
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, m int
	if _, err := fmt.Fscan(in, &n, &m); err != nil {
		return
	}
	var k int
	fmt.Fscan(in, &k)

	// Maps and constraints
	type Key uint64
	key := func(i, j int) Key { return Key((uint64(i) << 32) | uint64(j)) }

	M := make(map[Key]uint8) // interior fixed y_{ij} values (i<n, j<m)

	rowPresent := make([]bool, n+1)
	colPresent := make([]bool, m+1)
	rowRHS := make([]uint8, n+1)
	colRHS := make([]uint8, m+1)

	tPresent := false
	var tRHS uint8

	bit := func(c int) uint8 {
		if c == 1 {
			return 0
		}
		return 1
	}

	type entry struct{ a, b, c int }
	entries := make([]entry, 0, k)
	for i := 0; i < k; i++ {
		var a, b, c int
		fmt.Fscan(in, &a, &b, &c)
		entries = append(entries, entry{a, b, c})
	}

	var pmod int64
	fmt.Fscan(in, &pmod)

	// Quick impossibility due to parity of required row/col products
	if (n^m)&1 == 1 {
		fmt.Fprintln(out, 0%pmod)
		return
	}

	// Process entries to set up constraints
	for _, e := range entries {
		a, b, c := e.a, e.b, e.c
		v := bit(c)
		if a < n && b < m {
			M[key(a, b)] = v
		} else if a < n && b == m {
			rowPresent[a] = true
			rowRHS[a] = v ^ 1
		} else if a == n && b < m {
			colPresent[b] = true
			colRHS[b] = v ^ 1
		} else if a == n && b == m {
			tPresent = true
			if n&1 == 1 {
				tRHS = v ^ 1
			} else {
				tRHS = v
			}
		}
	}

	// Adjust RHS by subtracting known interior fixed variables
	if len(M) > 0 {
		for kx, v := range M {
			i := int(uint64(kx) >> 32)
			j := int(uint64(kx) & 0xffffffff)
			if rowPresent[i] {
				rowRHS[i] ^= v
			}
			if colPresent[j] {
				colRHS[j] ^= v
			}
			if tPresent {
				tRHS ^= v
			}
		}
	}

	// Build R and C lists and maps
	Rlist := make([]int, 0)
	Clist := make([]int, 0)
	rowIdx := make([]int, n+1)
	colIdx := make([]int, m+1)
	for i := 1; i <= n-1; i++ {
		if rowPresent[i] {
			rowIdx[i] = len(Rlist)
			Rlist = append(Rlist, i)
		} else {
			rowIdx[i] = -1
		}
	}
	for j := 1; j <= m-1; j++ {
		if colPresent[j] {
			colIdx[j] = len(Clist)
			Clist = append(Clist, j)
		} else {
			colIdx[j] = -1
		}
	}
	r := len(Rlist)
	c := len(Clist)

	// Precompute membership flags
	rowInR := make([]bool, n+1)
	colInC := make([]bool, m+1)
	for _, i := range Rlist {
		rowInR[i] = true
	}
	for _, j := range Clist {
		colInC[j] = true
	}

	// Counts for singletons and D
	rowFixedOutsideC := make([]int, n+1)
	colFixedOutsideR := make([]int, m+1)
	fixedNeither := 0
	for kx := range M {
		i := int(uint64(kx) >> 32)
		j := int(uint64(kx) & 0xffffffff)
		if i <= n-1 && j <= m-1 {
			if rowInR[i] && !colInC[j] {
				rowFixedOutsideC[i]++
			}
			if colInC[j] && !rowInR[i] {
				colFixedOutsideR[j]++
			}
			if !rowInR[i] && !colInC[j] {
				fixedNeither++
			}
		}
	}

	outC := (m - 1) - c
	outR := (n - 1) - r

	rowSingleton := make([]bool, n+1)
	colSingleton := make([]bool, m+1)
	hasAnySingleton := false
	for _, i := range Rlist {
		if outC-rowFixedOutsideC[i] > 0 {
			rowSingleton[i] = true
			hasAnySingleton = true
		}
	}
	for _, j := range Clist {
		if outR-colFixedOutsideR[j] > 0 {
			colSingleton[j] = true
			hasAnySingleton = true
		}
	}

	totalNeither := ((n - 1) - r) * ((m - 1) - c)
	D := totalNeither-fixedNeither > 0

	// Build DSU with edges between R and C where (i,j) is not fixed
	var dsu *DSU
	sz := r + c
	if sz > 0 {
		dsu = NewDSU(sz)
		for ii, i := range Rlist {
			for jj, j := range Clist {
				if _, ok := M[key(i, j)]; !ok {
					dsu.Union(ii, r+jj)
				}
			}
		}
	}

	// Component properties
	compSize := make([]int, sz)
	compParity := make([]uint8, sz)
	compHasSingleton := make([]bool, sz)

	// Initialize parity and singleton flags per vertex
	if sz > 0 {
		for v := 0; v < sz; v++ {
			root := dsu.Find(v)
			compSize[root]++
			if v < r {
				i := Rlist[v]
				compParity[root] ^= rowRHS[i]
				if rowSingleton[i] {
					compHasSingleton[root] = true
				}
			} else {
				j := Clist[v-r]
				compParity[root] ^= colRHS[j]
				if colSingleton[j] {
					compHasSingleton[root] = true
				}
			}
		}
	}

	// Consistency checks per component
	consistent := true
	d := 0
	if sz > 0 {
		for v := 0; v < sz; v++ {
			if dsu.Find(v) != v {
				continue
			}
			if !compHasSingleton[v] && compParity[v]&1 == 1 {
				consistent = false
				break
			}
			add := compSize[v] - 1
			if compHasSingleton[v] {
				add++
			}
			d += add
		}
	}
	if !consistent {
		fmt.Fprintln(out, 0%pmod)
		return
	}

	// Additional T constraint consistency when g not in span
	gInSpan := hasAnySingleton || D
	if tPresent && !gInSpan {
		var sumRows uint8 = 0
		for _, i := range Rlist {
			sumRows ^= rowRHS[i]
		}
		if sumRows != tRHS {
			fmt.Fprintln(out, 0%pmod)
			return
		}
	}

	// Number of variables
	V := (n - 1) * (m - 1) - len(M)

	// Rank
	rank := d
	if tPresent && gInSpan {
		rank++
	}

	deg := int64(V - rank)
	if deg < 0 {
		fmt.Fprintln(out, 0%pmod)
		return
	}
	ans := powMod2(deg, pmod)
	fmt.Fprintln(out, ans%pmod)
}