Farmer John's largest pasture can be regarded as a large 2D grid of square "cells" (picture a huge chess board). Currently, there are?NN?cows occupying some of these cells (1≤N≤25001≤N≤2500).
Farmer John wants to build a fence that will enclose a rectangular region of cells; the rectangle must be oriented so its sides are parallel with the?xx?and?yy?axes, and it could be as small as a single cell. Please help him count the number of distinct subsets of cows that he can enclose in such a region. Note that the empty subset should be counted as one of these.
The first line contains a single integer?NN. Each of the next?NN?lines Each of the next?NN?lines contains two space-separated integers, indicating the?(x,y)(x,y)?coordinates of a cow's cell. All?xx?coordinates are distinct from each-other, and all?yy?coordinates are distinct from each-other. All?xx?and?yy?values lie in the range?0…1090…109.
The number of subsets of cows that FJ can fence off. It can be shown that this quantity fits within a signed 64-bit integer (e.g., a "long long" in C/C++).
4 0 2 1 0 2 3 3 5
13
There are?2424?subsets in total. FJ cannot create a fence enclosing only cows 1, 2, and 4, or only cows 2 and 4, or only cows 1 and 4, so the answer is?24?3=16?3=1324?3=16?3=13.
Problem credits: Benjamin Qi
[/hide]
(Analysis by Benjamin Qi)
First, compress all of the?xx?and?yy?coordinates so that everything is in the range?[0,N?1][0,N?1].
For each nonempty subset of cows that can be fenced off, consider the rectangle of the minimum size that encloses the subset. This rectangle must contain a cow on each of its four sides. Conversely, each rectangle with a cow on each of its sides corresponds to a unique subset of cows that can be fenced off. Due to the condition that all coordinates are distinct, each side will contain exactly one cow.
A naive approach would be to test whether each of the?O(N4)O(N4)?possible rectangles satisfies this condition, giving an?O(N5)O(N5)?time solution. For additional an?O(N4)O(N4)?time solution, check each rectangle in?O(1)O(1)?time.
For full credit, we need an?O(N2)O(N2)?solution. Suppose that we fix the cows?a=(xa,ya)a=(xa,ya)?and?b=(xb,yb)b=(xb,yb)?on the bottom and top sides of the rectangle (so?ya≤ybya≤yb). Then the cow?cc?on the left side of the rectangle must satisfy?xc≤min(xa,xb)xc≤min(xa,xb)?and?ya≤yc≤ybya≤yc≤yb. Similarly, the cow?dd?on the right side of the rectangle must satisfy?max(xa,xb)≤xdmax(xa,xb)≤xd?and?ya≤yd≤ybya≤yd≤yb. In other words, the number of possibilities for?cc?is the number of points in the rectangle?[0,min(xa,xb)]×[ya,yb][0,min(xa,xb)]×[ya,yb]?while the number of possibilities for?dd?is the number of cows in the rectangle?[max(xa,xb),N?1]×[ya,yb][max(xa,xb),N?1]×[ya,yb]. We can compute these quantities using?2D prefix sums.
Brian Dean's code:
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> Point;
bool ycomp(Point p, Point q) { return p.second < q.second; }
const int MAX_N = 2500;
int N, Psum[MAX_N+1][MAX_N+1];
Point P[MAX_N];
int rsum(int x1, int y1, int x2, int y2)
{
return Psum[x2+1][y2+1] - Psum[x2+1][y1] - Psum[x1][y2+1] + Psum[x1][y1];
}
int main(void)
{
cin >> N;
for (int i=0; i<N; i++) {
int x, y;
cin >> x >> y;
P[i] = make_pair(x,y);
}
sort(P, P+N);
for (int i=0; i<N; i++) P[i].first = i+1;
sort(P, P+N, ycomp);
for (int i=0; i<N; i++) P[i].second = i+1;
for (int i=0; i<N; i++) Psum[P[i].first][P[i].second] = 1;
for (int i=1; i<=N; i++)
for (int j=1; j<=N; j++)
Psum[i][j] += Psum[i-1][j] + Psum[i][j-1] - Psum[i-1][j-1];
long long answer = 0;
for (int i=0; i<N; i++)
for (int j=i; j<N; j++) {
int x1 = min(P[i].first, P[j].first) - 1;
int x2 = max(P[i].first, P[j].first) - 1;
answer += rsum(0,i,x1,j) * rsum(x2,i,N-1,j);
}
cout << answer + 1 << "\n";
}
Danny Mittal's code:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class RectangularPasture {
static int[][] sums;
static int getSum(int fromX, int toX, int fromY, int toY) {
return sums[toX][toY] - sums[fromX - 1][toY] - sums[toX][fromY - 1] + sums[fromX - 1][fromY - 1];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] xs = new int[n];
int[] ys = new int[n];
Integer[] cows = new Integer[n];
for (int j = 0; j < n; j++) {
xs[j] = in.nextInt();
ys[j] = in.nextInt();
cows[j] = j;
}
Arrays.sort(cows, Comparator.comparingInt(j -> xs[j]));
for (int x = 1; x <= n; x++) {
xs[cows[x - 1]] = x;
}
Arrays.sort(cows, Comparator.comparingInt(j -> ys[j]));
for (int y = 1; y <= n; y++) {
ys[cows[y - 1]] = y;
}
sums = new int[n + 1][n + 1];
for (int j = 0; j < n; j++) {
sums[xs[j]][ys[j]]++;
}
for (int x = 0; x <= n; x++) {
for (int y = 0; y <= n; y++) {
if (x > 0) {
sums[x][y] += sums[x - 1][y];
}
if (y > 0) {
sums[x][y] += sums[x][y - 1];
}
if (x > 0 && y > 0) {
sums[x][y] -= sums[x - 1][y - 1];
}
}
}
long answer = n + 1;
for (int j = 0; j < n; j++) {
for (int k = j + 1; k < n; k++) {
answer += getSum(Math.min(xs[j], xs[k]), Math.max(xs[j], xs[k]), 1, Math.min(ys[j], ys[k]))
* getSum(Math.min(xs[j], xs[k]), Math.max(xs[j], xs[k]), Math.max(ys[j], ys[k]), n);
}
}
System.out.println(answer);
}
}
[/hide]
以上就是關(guān)于【USACO 2020 December Contest, Silver Problem 2. Rectangular Pasture】的解答,如需了解學(xué)校/賽事/課程動態(tài),可至翰林教育官網(wǎng)獲取更多信息。
往期文章閱讀推薦:
NOAI人工智能奧賽 2026-2027 活動章程出爐:新規(guī)則必看!
NOAI、UKOAI、USAAIO三大AI奧賽新賽季全面啟動:留學(xué)申請的“核武器”來了!

? 2026. All Rights Reserved. 滬ICP備2023009024號-1