Max pooling passes gradient only to the input that won each window. With overlapping windows (stride < kernel), one input can win several windows and must accumulate their gradients.
For x: (N, C, H, W) with a square k × k window and a stride (no padding):
maxpool_forward(x, k, stride): return (out, cache) with out of shape (N, C, oh, ow), where oh = (H - k) // stride + 1maxpool_backward(dout, cache): return dx. Within each window, the winner is the first maximum in row-major order.