← Home
For problem statement at 1000-1999/1400-1499/1420-1429/1423/problemH.txt this is a correct solution, but verifier at 1000-1999/1400-1499/1420-1429/1423/verifierH.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"os"
)

type rec struct {
	a, b   int32
	sizeA  int32
}

type DSU struct {
	parent []int32
	size   []int32
	stack  []rec
}

func NewDSU(n int) *DSU {
	p := make([]int32, n+1)
	sz := make([]int32, n+1)
	for i := 1; i <= n; i++ {
		p[i] = int32(i)
		sz[i] = 1
	}
	return &DSU{parent: p, size: sz, stack: make([]rec, 0, 1<<20)}
}

func (d *DSU) Find(x int32) int32 {
	for d.parent[x] != x {
		x = d.parent[x]
	}
	return x
}

func (d *DSU) Union(x, y int32) {
	x = d.Find(x)
	y = d.Find(y)
	if x == y {
		d.stack = append(d.stack, rec{0, 0, 0})
		return
	}
	if d.size[x] < d.size[y] {
		x, y = y, x
	}
	d.stack = append(d.stack, rec{x, y, d.size[x]})
	d.parent[y] = x
	d.size[x] += d.size[y]
}

func (d *DSU) Rollback() {
	last := d.stack[len(d.stack)-1]
	d.stack = d.stack[:len(d.stack)-1]
	if last.a == 0 {
		return
	}
	d.parent[last.b] = last.b
	d.size[last.a] = last.sizeA
}

type FastReader struct {
	r *bufio.Reader
}

func NewFastReader() *FastReader {
	return &FastReader{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}

func (fr *FastReader) NextInt() int {
	sign := 1
	val := 0
	c, err := fr.r.ReadByte()
	for (c < '0' || c > '9') && c != '-' {
		c, err = fr.r.ReadByte()
		if err != nil {
			return 0
		}
	}
	if c == '-' {
		sign = -1
		c, err = fr.r.ReadByte()
		if err != nil {
			return 0
		}
	}
	for c >= '0' && c <= '9' {
		val = val*10 + int(c-'0')
		c, err = fr.r.ReadByte()
		if err != nil {
			break
		}
	}
	return sign * val
}

type Q2 struct {
	z   int32
	idx int
}

func addCount(node, l, r, ql, qr int, cnt []int32) {
	if ql <= l && r <= qr {
		cnt[node]++
		return
	}
	m := (l + r) >> 1
	if ql <= m {
		addCount(node<<1, l, m, ql, qr, cnt)
	}
	if qr > m {
		addCount(node<<1|1, m+1, r, ql, qr, cnt)
	}
}

func addFill(node, l, r, ql, qr int, u, v int32, off, cnt []int32, Eu, Ev []int32) {
	if ql <= l && r <= qr {
		pos := int(off[node] + cnt[node])
		Eu[pos] = u
		Ev[pos] = v
		cnt[node]++
		return
	}
	m := (l + r) >> 1
	if ql <= m {
		addFill(node<<1, l, m, ql, qr, u, v, off, cnt, Eu, Ev)
	}
	if qr > m {
		addFill(node<<1|1, m+1, r, ql, qr, u, v, off, cnt, Eu, Ev)
	}
}

func dfs(node, l, r int, off, cnt []int32, Eu, Ev []int32, dsu *DSU, queriesByDay [][]Q2, ans []int) {
	stackSz := len(dsu.stack)
	start := int(off[node])
	end := start + int(cnt[node])
	for i := start; i < end; i++ {
		dsu.Union(Eu[i], Ev[i])
	}
	if l == r {
		for _, q := range queriesByDay[l] {
			root := dsu.Find(q.z)
			ans[q.idx] = int(dsu.size[root])
		}
	} else {
		m := (l + r) >> 1
		dfs(node<<1, l, m, off, cnt, Eu, Ev, dsu, queriesByDay, ans)
		dfs(node<<1|1, m+1, r, off, cnt, Eu, Ev, dsu, queriesByDay, ans)
	}
	for len(dsu.stack) > stackSz {
		dsu.Rollback()
	}
}

func main() {
	fr := NewFastReader()
	n := fr.NextInt()
	q := fr.NextInt()
	k := fr.NextInt()

	type EdgeS struct {
		u, v int32
		s    int
	}
	edges := make([]EdgeS, 0, q)
	type QueryS struct {
		z   int32
		day int
		idx int
	}
	queries := make([]QueryS, 0, q)

	day := 0
	ansCount := 0
	for i := 0; i < q; i++ {
		t := fr.NextInt()
		if t == 1 {
			x := int32(fr.NextInt())
			y := int32(fr.NextInt())
			edges = append(edges, EdgeS{u: x, v: y, s: day})
		} else if t == 2 {
			z := int32(fr.NextInt())
			queries = append(queries, QueryS{z: z, day: day, idx: ansCount})
			ansCount++
		} else {
			day++
		}
	}
	maxDay := day
	dayCount := maxDay + 1

	queriesByDay := make([][]Q2, dayCount)
	for _, qq := range queries {
		queriesByDay[qq.day] = append(queriesByDay[qq.day], Q2{z: qq.z, idx: qq.idx})
	}

	if dayCount == 0 {
		// No days, but possible queries can't exist. Just print nothing.
		return
	}

	size := 4 * dayCount
	cnt := make([]int32, size)
	off := make([]int32, size)

	for _, e := range edges {
		l := e.s
		r := e.s + k - 1
		if r > maxDay {
			r = maxDay
		}
		if l <= r {
			addCount(1, 0, maxDay, l, r, cnt)
		}
	}

	var total int32 = 0
	for i := 1; i < size; i++ {
		if cnt[i] > 0 {
			off[i] = total
			total += cnt[i]
			cnt[i] = 0
		}
	}
	Eu := make([]int32, total)
	Ev := make([]int32, total)

	for _, e := range edges {
		l := e.s
		r := e.s + k - 1
		if r > maxDay {
			r = maxDay
		}
		if l <= r {
			addFill(1, 0, maxDay, l, r, e.u, e.v, off, cnt, Eu, Ev)
		}
	}

	dsu := NewDSU(n)
	ans := make([]int, ansCount)
	dfs(1, 0, maxDay, off, cnt, Eu, Ev, dsu, queriesByDay, ans)

	w := bufio.NewWriterSize(os.Stdout, 1<<20)
	for i := 0; i < ansCount; i++ {
		// manual int to bytes to avoid fmt overhead
		x := ans[i]
		if x == 0 {
			w.WriteByte('0')
			w.WriteByte('\n')
			continue
		}
		var buf [20]byte
		pos := 20
		for x > 0 {
			pos--
			buf[pos] = byte('0' + x%10)
			x /= 10
		}
		w.Write(buf[pos:])
		w.WriteByte('\n')
	}
	w.Flush()
}