(Analysis by Benjamin Qi)

First, compress all of the $x$ and $y$ coordinates so that everything is in the range $[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 $\mathcal{O}(N^4)$ possible rectangles satisfies this condition, giving an $\mathcal{O}(N^5)$ time solution. For additional an $\mathcal{O}(N^4)$ time solution, check each rectangle in $\mathcal{O}(1)$ time.

For full credit, we need an $\mathcal{O}(N^2)$ solution. Suppose that we fix the cows $a=(x_a,y_a)$ and $b=(x_b,y_b)$ on the bottom and top sides of the rectangle (so $y_a\le y_b$). Then the cow $c$ on the left side of the rectangle must satisfy $x_c\le \min(x_a,x_b)$ and $y_a\le y_c\le y_b$. Similarly, the cow $d$ on the right side of the rectangle must satisfy $\max(x_a,x_b)\le x_d$ and $y_a\le y_d\le y_b$. In other words, the number of possibilities for $c$ is the number of points in the rectangle $[0,\min(x_a,x_b)]\times [y_a,y_b]$ while the number of possibilities for $d$ is the number of cows in the rectangle $[\max(x_a,x_b),N-1]\times [y_a,y_b]$. 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);
    }
}