← Home
```go
package main

import (
	"bufio"
	"fmt"
	"math/bits"
	"os"
	"sort"
)

const INF int64 = 1 << 60

type Edge struct {
	to   int
	d    int
	cost int64
}

func mult(a, b []int64, s int) []int64 {
	c := make([]int64, s*s)
	for i := range c {
		c[i] = INF
	}
	for i := 0; i < s; i++ {
		ai := a[i*s : (i+1)*s]
		ci := c[i*s : (i+1)*s]
		for k := 0; k < s; k++ {
			av := ai[k]
			if av >= INF {
				continue
			}
			bk := b[k*s : (k+1)*s]
			for j := 0; j < s; j++ {
				bv := bk[j]
				if bv >= INF {
					continue
				}
				val := av + bv
				if val < ci[j] {
					ci[j] = val
				}
			}
		}
	}
	return c
}

func applyMat(dp, mat []int64, s int) []int64 {
	res := make([]int64, s)
	for i := range res {
		res[i] = INF
	}
	for u := 0; u < s; u++ {
		du := dp[u]
		if du >= INF {
			continue
		}
		row := mat[u*s : (u+1)*s]
		for v := 0; v < s; v++ {
			mv := row[v]
			if mv >= INF {
				continue
			}
			val := du + mv
			if val < res[v] {
				res[v] = val
			}
		}
	}
	return res
}

func applyPow(dp []int64, steps int, powers [][]int64, s int) []int64 {
	bit := 0
	for steps > 0 {
		if steps&1 == 1 {
			dp = applyMat(dp, powers[bit], s)
		}
		steps >>= 1
		bit++
	}
	return dp
}

func applyDirect(dp []int64, edges [][]Edge, pos, n, k, s int, special map[int]int64) []int64 {
	limit := n - pos
	if limit > k {
		limit = k
	}
	extra := make([]int64, limit+1)
	for d := 1; d <= limit; d++ {
		if w, ok := special[pos+d]; ok {
			extra[d] = w
		}
	}
	res := make([]int64, s)
	for i := range res {
		res[i] = INF
	}
	for u := 0; u < s; u++ {
		du := dp[u]
		if du >= INF {
			continue
		}
		for _, e := range edges[u] {
			if e.d > limit {
				continue
			}
			val := du + e.cost
			if e.d > 0 {
				val += extra[e.d]
			}
			if val < res[e.to] {
				res[e.to] = val
			}
		}
	}
	return res
}

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

	var x, k, n, q int
	fmt.Fscan(in, &x, &k, &n, &q)

	c := make([]int64, k)
	for i := 0; i < k; i++ {
		fmt.Fscan(in, &c[i])
	}

	special := make(map[int]int64, q)
	ps := make([]int, 0, q)
	for i := 0; i < q; i++ {
		var p int
		var w int64
		fmt.Fscan(in, &p, &w)
		special[p] = w
		ps = append(ps, p)
	}

	maxMask := 1 << k
	id := make([]int, maxMask)
	for i := range id {
		id[i] = -1
	}
	masks := make([]int, 0)
	for m := 0; m < maxMask; m++ {
		if bits.OnesCount(uint(m)) == x {
			id[m] = len(masks)
			masks = append(masks, m)
		}
	}

	s := len(masks)
	edges := make([][]Edge, s)

	for u, m := range masks {
		base := m >> 1
		if m&1 == 0 {
			edges[u] = []Edge{{to: id[base], d: 0, cost: 0}}
		} else {
			arr := make([]Edge, 0, k)
			for d := 1; d <= k; d++ {
				var vmask int
				if d < k {
					if (m>>d)&1 == 1 {
						continue
					}
					vmask = base | (1 << (d - 1))
				} else {
					vmask = base | (1 << (k - 1))
				}
				arr = append(arr, Edge{to: id[vmask], d: d, cost: c[d-1]})
			}
			edges[u] = arr
		}
	}

	A := make([]int64, s*s)
	for i := range A {
		A[i] = INF
	}
	for u := 0; u < s; u++ {
		for _, e := range edges[u] {
			idx := u*s + e.to
			if e.cost < A[idx] {
				A[idx] = e.cost
			}
		}
	}

	T := n - x + 1
	maxGap := T - 1

	powers := [][]int64{A}
	for (1 << uint(len(powers))) <= maxGap {
		last := powers[len(powers)-1]
		powers = append(powers, mult(last, last, s))
	}

	critSet := make(map[int]struct{})
	upper := T - 1

	tailStart := n - k + 1
	if tailStart < 1 {
		tailStart = 1
	}
	for i := tailStart; i <= upper; i++ {
		critSet[i] = struct{}{}
	}

	for _, p := range ps {
		for d := 1; d <= k; d++ {
			pos := p - d
			if pos >= 1 && pos <= upper {
				critSet[pos] = struct{}{}
			}
		}
	}

	crit := make([]int, 0, len(critSet))
	for pos := range critSet {
		crit = append(crit, pos)
	}
	sort.Ints(crit)

	initMask := (1 << x) - 1
	initID := id[initMask]

	dp := make([]int64, s)
	for i := range dp {
		dp[i] = INF
	}
	dp[initID] = 0

	cur := 1
	for _, pos := range crit {
		if pos < cur {
			continue
		}
		if cur < pos {
			dp = applyPow(dp, pos-cur, powers, s)
			cur = pos
		}
		dp = applyDirect(dp, edges, cur, n, k, s, special)
		cur++
	}

	if cur < T {
		dp = applyPow(dp, T-cur, powers, s)
	}

	fmt.Fprintln(out, dp[initID])
}
```