Official

F - One Fourth Editorial by en_translator


In this editorial, we denote by \(S\) the area of the entire polygon. Also, we identify Vertex \(N+1\) with Vertex \(1\), Vertex \(N+2\) with Vertex \(2\), and so on.

First, we introduce the \(O(N^3)\) solution.

  • For all non-adjacent pair of integer \((p,q)\), do the following.
  • Find the answer when the pizza is cut along the line passing through Vertices \(p\) and \(q\) and the piece containing Vertex \((p+1)\) is eaten.
    • Here, we need to find the area of the piece containing Vertex \((p+1)\).
  • The minimum value of these values is the sought value.

This can be improved to \(O(N^2)\) as follows.

  • For each Vertex \(p\), do the following.
    • For each Vertex \(q=(p+1), (p+2), \dots (p+N-2)\), do the following.
      • Add the triangle whose vertices are Vertices \(p,q,(q+1)\) to the piece to eat. Now, the piece to eat coincides with that when the pizza is cut along the line passing through Vertices \(p\) and \(q\) and the piece containing Vertex \((p+1)\) is eaten.

Furthermore, this solution can be improved to \(O(N)\) with the following “sliding window” trick.

  • Initialize Vertex \(q=2\), and let the piece to eat be empty.
  • For each vertex \(p=1,2,\dots,N\), do the following.
    • Let \(E\) be the area of the current piece to eat.
    • While \(E < S/4\), add the triangle whose vertices are \(p,q,(q+1)\) to the piece to eat, and increment \(q\).
    • Then, remove the triangle whose vertices are \(p,(p+1),q\) from the piece to eat.

We will justify the sliding window trick. Suppose that we have \(q=Q\) when the process for \(p=i\) has ended. At this time, for \(p>i\), letting \(q<Q\) never yields the optimal value, because \(p=i,q=Q-1\) already yields the area of the piece to eat is less than \(E/4\), so increasing \(p\) furthermore do never make the area of the piece to eat closer to \(E/4\) than when \(p=i,q=Q-1\).

In the Sample Code below, we use the Sample Code for Typical 90 Problems of Competitive Programming, Problem 41 (Japanese) for the implementation of geometry libraries. (tips: With this implementation, implementing convex hull is also easy.)

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

struct Point {
	long long px, py;
};

Point operator+(const Point& a1, const Point& a2) {
	return Point{ a1.px + a2.px, a1.py + a2.py };
}

Point operator-(const Point& a1, const Point& a2) {
	return Point{ a1.px - a2.px, a1.py - a2.py };
}

bool operator<(const Point& a1, const Point& a2) {
	if (a1.px < a2.px) return true;
	if (a1.px > a2.px) return false;
	if (a1.py < a2.py) return true;
	return false;
}

// Find the cross product of p1 and p2
long long crs(Point p1, Point p2) {
	return p1.px * p2.py - p1.py * p2.px;
}

int main(){
  int n;
  cin >> n;
  vector<Point> pts(n);
  for(int i=0;i<n;i++){cin >> pts[i].px >> pts[i].py;}

  long long s=0;
  for(int i=2;i<n;i++){
    s+=abs(crs(pts[i-1]-pts[0],pts[i]-pts[0]));
  }

  long long res=8e18,e=0;
  int q=1;
  for(int p=0;p<n;p++){
    while(4*e<s){
      e+=abs(crs(pts[q]-pts[p],pts[(q+1)%n]-pts[p]));
      q++;q%=n;
      res=min(res,abs(4*e-s));
    }
    e-=abs(crs(pts[p]-pts[q],pts[(p+1)%n]-pts[q]));
    res=min(res,abs(4*e-s));
  }
  cout << res << '\n';
  return 0;
}

posted:
last update: