package main
import (
"bufio"
"fmt"
"io"
"os"
)
type Point struct {
x, y int64
a int64
}
type Node struct {
xmin, xmax int64
ymin, ymax int64
sum int64
x, y int64
val int64
left, right int32
}
var seed uint32 = 12345
func fastRand() uint32 {
seed ^= seed << 13
seed ^= seed >> 17
seed ^= seed << 5
return seed
}
func sortXY(a []Point, l, r int) {
if l >= r {
return
}
idx := l + int(fastRand()%uint32(r-l+1))
px, py := a[idx].x, a[idx].y
i, j := l, r
for i <= j {
for a[i].x < px || (a[i].x == px && a[i].y < py) {
i++
}
for a[j].x > px || (a[j].x == px && a[j].y > py) {
j--
}
if i <= j {
a[i], a[j] = a[j], a[i]
i++
j--
}
}
sortXY(a, l, j)
sortXY(a, i, r)
}
func quickSelectX(a []Point, l, r, k_idx int) {
for l < r {
p := a[l+int(fastRand()%uint32(r-l+1))].x
i, j := l, r
for i <= j {
for a[i].x < p {
i++
}
for a[j].x > p {
j--
}
if i <= j {
a[i], a[j] = a[j], a[i]
i++
j--
}
}
if k_idx <= j {
r = j
} else if k_idx >= i {
l = i
} else {
break
}
}
}
func quickSelectY(a []Point, l, r, k_idx int) {
for l < r {
p := a[l+int(fastRand()%uint32(r-l+1))].y
i, j := l, r
for i <= j {
for a[i].y < p {
i++
}
for a[j].y > p {
j--
}
if i <= j {
a[i], a[j] = a[j], a[i]
i++
j--
}
}
if k_idx <= j {
r = j
} else if k_idx >= i {
l = i
} else {
break
}
}
}
type Scanner struct {
buf []byte
pos int
}
func NewScanner() *Scanner {
b, _ := io.ReadAll(os.Stdin)
return &Scanner{buf: b, pos: 0}
}
func (s *Scanner) NextInt() int64 {
for s.pos < len(s.buf) && s.buf[s.pos] <= ' ' {
s.pos++
}
if s.pos >= len(s.buf) {
return 0
}
sign := int64(1)
if s.buf[s.pos] == '-' {
sign = -1
s.pos++
}
var res int64
for s.pos < len(s.buf) && s.buf[s.pos] > ' ' {
res = res*10 + int64(s.buf[s.pos]-'0')
s.pos++
}
return res * sign
}
var nodes []Node
var A, B, S []int64
var L_bound, R_bound []int64
var k int
func query(node int32) int64 {
if node == -1 {
return 0
}
n := &nodes[node]
isInsideAll := true
for j := 0; j < k; j++ {
A_j := A[j]
B_j := B[j]
var minVal, maxVal int64
if A_j >= 0 {
minVal += A_j * n.xmin
maxVal += A_j * n.xmax
} else {
minVal += A_j * n.xmax
maxVal += A_j * n.xmin
}
if B_j >= 0 {
minVal += B_j * n.ymin
maxVal += B_j * n.ymax
} else {
minVal += B_j * n.ymax
maxVal += B_j * n.ymin
}
if minVal > R_bound[j] || maxVal < L_bound[j] {
return 0
}
if minVal < L_bound[j] || maxVal > R_bound[j] {
isInsideAll = false
}
}
if isInsideAll {
return n.sum
}
var ans int64
pointInside := true
for j := 0; j < k; j++ {
v := A[j]*n.x + B[j]*n.y
if v < L_bound[j] || v > R_bound[j] {
pointInside = false
break
}
}
if pointInside {
ans += n.val
}
ans += query(n.left)
ans += query(n.right)
return ans
}
func main() {
sc := NewScanner()
k = int(sc.NextInt())
n := int(sc.NextInt())
q := int(sc.NextInt())
if k == 0 && n == 0 && q == 0 {
return
}
vx := make([]int64, k)
vy := make([]int64, k)
for i := 0; i < k; i++ {
vx[i] = sc.NextInt()
vy[i] = sc.NextInt()
}
A = make([]int64, k)
B = make([]int64, k)
S = make([]int64, k)
L_bound = make([]int64, k)
R_bound = make([]int64, k)
for j := 0; j < k; j++ {
A[j] = -vy[j]
B[j] = vx[j]
var s int64
for i := 0; i < k; i++ {
val := A[j]*vx[i] + B[j]*vy[i]
if val < 0 {
s -= val
} else {
s += val
}
}
S[j] = s
}
rawPts := make([]Point, n)
for i := 0; i < n; i++ {
rawPts[i].x = sc.NextInt()
rawPts[i].y = sc.NextInt()
rawPts[i].a = sc.NextInt()
}
if n > 0 {
sortXY(rawPts, 0, n-1)
}
var pts []Point
for _, p := range rawPts {
if len(pts) > 0 && pts[len(pts)-1].x == p.x && pts[len(pts)-1].y == p.y {
pts[len(pts)-1].a += p.a
} else {
pts = append(pts, p)
}
}
m := len(pts)
nodes = make([]Node, m)
var build func(l, r int, depth int) int32
build = func(l, r int, depth int) int32 {
if l > r {
return -1
}
mid := l + (r-l)/2
if depth%2 == 0 {
quickSelectX(pts, l, r, mid)
} else {
quickSelectY(pts, l, r, mid)
}
left := build(l, mid-1, depth+1)
right := build(mid+1, r, depth+1)
xmin, xmax := pts[mid].x, pts[mid].x
ymin, ymax := pts[mid].y, pts[mid].y
sum := pts[mid].a
if left != -1 {
if nodes[left].xmin < xmin {
xmin = nodes[left].xmin
}
if nodes[left].xmax > xmax {
xmax = nodes[left].xmax
}
if nodes[left].ymin < ymin {
ymin = nodes[left].ymin
}
if nodes[left].ymax > ymax {
ymax = nodes[left].ymax
}
sum += nodes[left].sum
}
if right != -1 {
if nodes[right].xmin < xmin {
xmin = nodes[right].xmin
}
if nodes[right].xmax > xmax {
xmax = nodes[right].xmax
}
if nodes[right].ymin < ymin {
ymin = nodes[right].ymin
}
if nodes[right].ymax > ymax {
ymax = nodes[right].ymax
}
sum += nodes[right].sum
}
nodes[mid] = Node{
xmin: xmin,
xmax: xmax,
ymin: ymin,
ymax: ymax,
sum: sum,
x: pts[mid].x,
y: pts[mid].y,
val: pts[mid].a,
left: left,
right: right,
}
return int32(mid)
}
root := int32(-1)
if m > 0 {
root = build(0, m-1, 0)
}
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
for i := 0; i < q; i++ {
px := sc.NextInt()
py := sc.NextInt()
t := sc.NextInt()
for j := 0; j < k; j++ {
base := A[j]*px + B[j]*py
margin := t * S[j]
L_bound[j] = base - margin
R_bound[j] = base + margin
}
ans := query(root)
fmt.Fprintln(out, ans)
}
}