Problem:
Share the Ruins Preservation
Two organizations International Community for Preservation of Constructions (ICPC) and Japanese Archaeologist Group (JAG) engage in ruins preservation. Recently, many ruins were found in a certain zone. The two organizations decided to share the preservation of the ruins by assigning some of the ruins to ICPC and the other ruins to JAG.
Now, ICPC and JAG make a rule for assignment as follows:
Draw a vertical straight line from the north to the south, avoiding to intersect ruins.
Ruins located to the west of the line are preserved by ICPC. On the other hand, ruins located to the east of the line are preserved by JAG. (It is possible that no ruins are located to the east/west of the line; in this case, ICPC/JAG will preserve no ruins.)
A problem is where to draw a straight line. For each organization, the way to preserve its assigned ruins is to make exactly one fence such that all the assigned ruins are in the region surrounded by the fence. Furthermore, they should minimize the length of such a fence for their budget. If the surrounded areas are vast, expensive costs will be needed to maintain the inside of areas. Therefore, they want to minimize the total preservation cost, i.e. the sum of the areas surrounded by two fences. Your task is to write a program computing the minimum sum of the areas surrounded by two fences, yielded by drawing an appropriate straight line.
Input
The input consists of a single test case.
$N$
$x_1$ $y_1$
$x_2$ $y_2$
...
$x_N$ $y_N$
The first line contains an integer $N$ ($1 \leq N \leq 100,000$), which is the number of founded ruins. The following $N$ lines represent the location of the ruins. The $i$-th line of them consists of two integers $x_i$ and $y_i$, which indicate the location of the $i$-th ruin is $x_i$ east and $y_i$ north from a certain location in the zone. You can assume the following things for the ruins:
$-10^9 \leq x_i, y_i \leq 10^9$
You can ignore the sizes of ruins. That is, you can assume ruins are points.
No pair of ruins has the same location.
Output
Print the minimum total preservation cost yielded by drawing an appropriate straight line. You should round off the cost to the nearest integer.
Sample Input 1
8
-10 0
-10 5
-5 5
-5 0
10 0
10 -5
5 -5
5 0
Output for the Sample Input 1
50
Sample Input 2
5
0 0
0 1
0 2
1 0
1 1
Output for the Sample Input 2
0
Sample Input 3
6
1 5
1 6
0 5
0 -5
-1 -5
-1 -6
Output for the Sample Input 3
6
Sample Input 4
10
2 5
4 6
9 5
8 8
1 3
6 4
5 9
7 3
7 7
3 9
Output for the Sample Input 4
17

Submitted solutions:

code_snippet: #include<bits/stdc++.h>

#define PB push_back
#define MP make_pair
#define F first
#define S second

#define FRI freopen("zin.txt","r",stdin)
#define FRO freopen("out.txt","w",stdout)
#define DB(x) #x" =>",x
#define debug(args...) {dbg,args; cerr<<endl;}
#define RAD(x) ((x*PI)/180)
#define DEG(x) ((x*180)/PI)
#define NEX(x,y) ((x)==(y)-1?0:(x)+1)
#define PRE(x,y) ((x)==0?(y)-1:(x)-1)

#define EPS 1e-12
#define INF 10000000000007LL
#define MAXN 100005
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

class PT {
public:
    LL x, y;
    PT() {}
    PT(LL x, LL y) : x(x), y(y) {}
    PT(const PT &p) : x(p.x), y(p.y)    {}
    PT operator + (const PT &p)  const { return PT(x+p.x, y+p.y); }
    PT operator - (const PT &p)  const { return PT(x-p.x, y-p.y); }
};

LL SignedArea(PT a,PT b,PT c) {
    PT temp1(b.x-a.x,b.y-a.y),temp2(c.x-a.x,c.y-a.y);
    return temp1.x*temp2.y-temp1.y*temp2.x;
}

bool XYasscending(PT a,PT b) {
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

vector<PT>rawPts,U,L;
vector<LL>xCoords,hi,lo;
LL area[2][MAXN];

int main() {
//    FRI;
    int i,n;
    LL x,y,ans,r1,r2,leftLo,leftHi;
    PT pivot;
    scanf("%d",&n);
    for(i=0;i<n;i++) {
        scanf("%lld %lld",&x,&y);
        rawPts.PB(PT(x,y));
    }
    sort(rawPts.begin(),rawPts.end(),XYasscending);
    for(i=0;i<rawPts.size();i++) {
        if(i==0||rawPts[i].x!=rawPts[i-1].x) {
            xCoords.PB(rawPts[i].x);
            lo.PB(rawPts[i].y);
            hi.PB(rawPts[i].y);
        }
        hi[hi.size()-1]=rawPts[i].y;
    }
    area[0][0]=0;
    pivot=PT(xCoords[0],lo[0]);

    U.PB(PT(xCoords[0],lo[0]));
    U.PB(PT(xCoords[0],hi[0]));
    L.PB(PT(xCoords[0],hi[0]));
    L.PB(PT(xCoords[0],lo[0]));

    for(i=1;i<xCoords.size();i++) {
        area[0][i]=area[0][i-1];
//        cout<<"Considering "<<xCoords[i]<<" "<<hi[i]<<" "<<lo[i]<<endl;
//        cout<<"Initial "<<area[0][i]<<endl;
        while(true) {
            if(U.size()<2) break;
            if(SignedArea(U[U.size()-2],U[U.size()-1],PT(xCoords[i],hi[i]))>=0) {
                area[0][i]-=SignedArea(pivot,U[U.size()-2],U[U.size()-1]);
//                cout<<"Reduced "<<area[0][i]<<endl;
                U.pop_back();
            }
            else break;
        }
        U.PB(PT(xCoords[i],hi[i]));
        area[0][i]+=SignedArea(pivot,U[U.size()-2],U[U.size()-1]);
//        cout<<"Increased "<<area[0][i]<<endl;

        while(true) {
            if(L.size()<2) break;
            if(SignedArea(L[L.size()-2],L[L.size()-1],PT(xCoords[i],lo[i]))<=0) {
                area[0][i]+=SignedArea(pivot,L[L.size()-2],L[L.size()-1]);
//                cout<<"Reduced "<<area[0][i]<<endl;
                L.pop_back();
            }
            else break;
        }
        L.PB(PT(xCoords[i],lo[i]));
        area[0][i]-=SignedArea(pivot,L[L.size()-2],L[L.size()-1]);
//        cout<<"Increased "<<area[0][i]<<endl;

        area[0][i]-=SignedArea(pivot,PT(xCoords[i-1],hi[i-1]),PT(xCoords[i-1],lo[i-1]));
//        cout<<"Here "<<area[0][i]<<endl;
        area[0][i]+=SignedArea(pivot,PT(xCoords[i],hi[i]),PT(xCoords[i],lo[i]));
//        cout<<"Final "<<area[0][i]<<endl;
    }

    area[1][xCoords.size()-1]=0;
    pivot=PT(xCoords[xCoords.size()-1],lo[xCoords.size()-1]);

    U.clear();
    L.clear();

    U.PB(PT(xCoords[xCoords.size()-1],lo[xCoords.size()-1]));
    U.PB(PT(xCoords[xCoords.size()-1],hi[xCoords.size()-1]));
    L.PB(PT(xCoords[xCoords.size()-1],hi[xCoords.size()-1]));
    L.PB(PT(xCoords[xCoords.size()-1],lo[xCoords.size()-1]));

    for(i=xCoords.size()-2;i>=0;i--) {
        area[1][i]=area[1][i+1];
        while(true) {
            if(U.size()<2) break;
            if(SignedArea(U[U.size()-2],U[U.size()-1],PT(xCoords[i],hi[i]))<=0) {
                area[1][i]-=SignedArea(pivot,U[U.size()-2],U[U.size()-1]);
                U.pop_back();
            }
            else break;
        }
        U.PB(PT(xCoords[i],hi[i]));
        area[1][i]+=SignedArea(pivot,U[U.size()-2],U[U.size()-1]);

        while(true) {
            if(L.size()<2) break;
            if(SignedArea(L[L.size()-2],L[L.size()-1],PT(xCoords[i],lo[i]))>=0) {
                area[1][i]+=SignedArea(pivot,L[L.size()-2],L[L.size()-1]);
                L.pop_back();
            }
            else break;
        }
        L.PB(PT(xCoords[i],lo[i]));
        area[1][i]-=SignedArea(pivot,L[L.size()-2],L[L.size()-1]);

        area[1][i]-=SignedArea(pivot,PT(xCoords[i+1],hi[i+1]),PT(xCoords[i+1],lo[i+1]));
        area[1][i]+=SignedArea(pivot,PT(xCoords[i],hi[i]),PT(xCoords[i],lo[i]));
    }

    ans=abs(area[0][0])+abs(area[1][1]);
    for(i=1;i<xCoords.size()-1;i++) ans=min(ans,abs(area[0][i])+abs(area[1][i+1]));

    if(ans&1) cout<<(ans+1)/2<<endl;
    else cout<<ans/2<<endl;

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11432
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

long long X[100009];
long long Y[100009];
long long KEEP[100009];
long long MX[100009];
long long MI[100009];
long long ANS[100009],ANSS[100009];
vector<long long>vec,XX[100009];
map<long long,long long>mymap;

vector<pair<long long,long long> >U,L;

void prnt(pair<long long,long long> A)
{
    cout<<A.first<<" "<<A.second<<endl;
}

pair<long long,long long> minu(pair<long long,long long> A,pair<long long,long long> B)
{
    pair<long long,long long> C;
    C.first=-A.first*B.second+B.first*A.second;
    C.second=A.first*B.first;
    long long temp=__gcd(abs(C.first),abs(C.second));
    C.first/=temp;
    C.second/=temp;

    if(C.second<0)
    {
        C.first*=-1;
        C.second*=-1;
    }
    return C;
}

pair<long long,long long> get(pair<long long,long long> A,pair<long long,long long> B)
{
    pair<long long,long long> C;
    C.first=B.first-A.first;
    C.second=B.second-A.second;

    long long temp=__gcd(abs(C.first),abs(C.second));
    C.first/=temp;
    C.second/=temp;

    if(C.second<0)
    {
        C.first*=-1;
        C.second*=-1;
    }

    return C;
}

long long get_area(pair<long long,long long> A,pair<long long,long long> B , pair<long long,long long>C)
{
    long long ans=0;
    ans+=(A.first*B.second-A.second*B.first);
    ans+=(B.first*C.second-B.second*C.first);
    ans+=(C.first*A.second-C.second*A.first);
    return abs(ans);
}

int main()
{
    long long n,i,j,k,l,ans,ind,siz,mi,mx,sl,su,temp,now;
    pair<long long,long long> now_ans,prev;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        scanf("%lld%lld",&X[i],&Y[i]);
        vec.push_back(X[i]);
    }

    sort(vec.begin(),vec.end());

    ind=0;

    for(i=0;i<n;i++)
    {
        if(i) if(vec[i]==vec[i-1]) continue;

        mymap[vec[i]]=++ind;
        KEEP[ind]=vec[i];
    }

    for(i=1;i<=n;i++)
    {
        XX[mymap[X[i]]].push_back(Y[i]);
    }

    for(i=1;i<=ind;i++) sort(XX[i].begin(),XX[i].end());
    for(i=1;i<=ind;i++)
    {
        siz=XX[i].size();
        MI[i]=XX[i][0];
        MX[i]=XX[i][siz-1];
    }

    U.clear();
    L.clear();
    sl=0;
    su=0;

    for(i=1;i<=ind;i++)
    {

        temp=0;
        if(sl==0)
        {
            L.push_back(make_pair(KEEP[i],MI[i]));
            sl++;
        }
        else
        {
            prev=get(L[sl-1],make_pair(KEEP[i],MI[i]));
            now=sl-1;

            while(1)
            {
                if(now<0) break;
                now_ans=get(L[now],make_pair(KEEP[i],MI[i]));
                if(minu(now_ans,prev).first<0) break;
                prev=now_ans;
                now--;
            }

            for(j=sl-1;j>now+1;j--)
            {
                temp+=get_area(make_pair(KEEP[i],MI[i]),L[j],L[j-1]);
            }

            for(j=sl-1;j>now+1;j--) L.pop_back();
            L.push_back(make_pair(KEEP[i],MI[i]));
            sl=L.size();
        }


        if(su==0)
        {
            U.push_back(make_pair(KEEP[i],MX[i]));
            su++;
        }
        else
        {
            prev=get(U[su-1],make_pair(KEEP[i],MX[i]));
            now=su-1;
            while(1)
            {
                if(now<0) break;
                now_ans=get(U[now],make_pair(KEEP[i],MX[i]));
                if(minu(now_ans,prev).first>0) break;
                prev=now_ans;
                now--;
            }


            for(j=su-1;j>now+1;j--)
            {
                temp+=get_area(make_pair(KEEP[i],MX[i]),U[j],U[j-1]);
            }

            for(j=su-1;j>now+1;j--) U.pop_back();
            U.push_back(make_pair(KEEP[i],MX[i]));
            su=U.size();

        }

        if(i>1) temp+=(MX[i]-MI[i]+MX[i-1]-MI[i-1])*(KEEP[i]-KEEP[i-1]);

        ANS[i]=ANS[i-1]+temp;
    }

    U.clear();
    L.clear();
    sl=0;
    su=0;


    for(i=ind;i>=1;i--)
    {
        temp=0;
        if(sl==0)
        {
            L.push_back(make_pair(KEEP[i],MI[i]));
            sl++;
        }
        else
        {
            prev=get(L[sl-1],make_pair(KEEP[i],MI[i]));
            now=sl-1;
            while(1)
            {
                if(now<0) break;
                now_ans=get(L[now],make_pair(KEEP[i],MI[i]));
                if(minu(now_ans,prev).first>0) break;
                prev=now_ans;
                now--;
            }


            for(j=sl-1;j>now+1;j--)
            {
                temp+=get_area(make_pair(KEEP[i],MI[i]),L[j],L[j-1]);
            }

            for(j=sl-1;j>now+1;j--) L.pop_back();
            L.push_back(make_pair(KEEP[i],MI[i]));
            sl=L.size();
        }

        if(su==0)
        {
            U.push_back(make_pair(KEEP[i],MX[i]));
            su++;
        }
        else
        {
            prev=get(U[su-1],make_pair(KEEP[i],MX[i]));
            now=su-1;
            while(1)
            {
                if(now<0) break;
                now_ans=get(U[now],make_pair(KEEP[i],MX[i]));
                if(minu(now_ans,prev).first<0) break;
                prev=now_ans;
                now--;
            }


            for(j=su-1;j>now+1;j--)
            {
                temp+=get_area(make_pair(KEEP[i],MX[i]),U[j],U[j-1]);
            }

            for(j=su-1;j>now+1;j--) U.pop_back();
            U.push_back(make_pair(KEEP[i],MX[i]));
            su=U.size();

        }

        if(i<ind) temp+=(MX[i]-MI[i]+MX[i+1]-MI[i+1])*(-KEEP[i]+KEEP[i+1]);

        ANSS[i]=ANSS[i+1]+temp;
    }


    ans=1LL<<62;

    for(i=0;i<=ind;i++)
    {
        ans=min(ans,ANS[i]+ANSS[i+1]);
    }

    cout<<(1+ans)/2<<endl;



}
accuracy: 0.1
time_ms: 70
memory_kb: 11340
final_rank: 20

code_snippet: // AOJ #2786 Share the Ruins Preservation
// 2025.3.14

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct P { ll x, y; };

ll cross(const P &a, const P &b, const P &c) {
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

ll cross(const P &a, const P &b) {
    return a.x * b.y - a.y * b.x;
}

vector<ld> getPrefixArea(const vector<P>& pts) {
    int n = pts.size();
    vector<ld> pre(n, 0.0L);
    vector<P> L;
    vector<ld> LS;
    vector<P> U;
    vector<ld> US;
    for (int i = 0; i < n; i++){
        P p = pts[i];
        while(L.size() >= 2 && cross(L[L.size()-2], L[L.size()-1], p) <= 0) {
            L.pop_back();
            LS.pop_back();
        }
        if(L.empty()){
            L.push_back(p);
            LS.push_back(0);
        } else {
            L.push_back(p);
            ll c = cross(L[L.size()-2], p);
            ld sum = (LS.empty()? 0 : LS.back()) + c;
            LS.push_back(sum);
        }

        while(U.size() >= 2 && cross(U[U.size()-2], U[U.size()-1], p) >= 0) {
            U.pop_back();
            US.pop_back();
        }
        if(U.empty()){
            U.push_back(p);
            US.push_back(0);
        } else {
            U.push_back(p);
            ll c = cross(U[U.size()-2], p);
            ld sum = (US.empty()? 0 : US.back()) + c;
            US.push_back(sum);
        }

        if(i < 2) {
            pre[i] = 0.0L;
        } else {
            ld area2 = US.back() - LS.back();
            if(area2 < 0) area2 = -area2;
            pre[i] = area2 / 2.0L;
        }
    }
    return pre;
}

vector<ld> getSuffixArea(const vector<P>& pts) {
    int n = pts.size();
    vector<ld> suf(n, 0.0L);
    vector<P> L;
    vector<ld> LS;
    vector<P> U;
    vector<ld> US;
    for (int i = n-1; i >= 0; i--){
        P p = pts[i];
        while(L.size() >= 2 && cross(L[L.size()-2], L[L.size()-1], p) <= 0) {
            L.pop_back();
            LS.pop_back();
        }
        if(L.empty()){
            L.push_back(p);
            LS.push_back(0);
        } else {
            L.push_back(p);
            ll c = cross(L[L.size()-2], p);
            ld sum = (LS.empty()? 0 : LS.back()) + c;
            LS.push_back(sum);
        }

        while(U.size() >= 2 && cross(U[U.size()-2], U[U.size()-1], p) >= 0) {
            U.pop_back();
            US.pop_back();
        }
        if(U.empty()){
            U.push_back(p);
            US.push_back(0);
        } else {
            U.push_back(p);
            ll c = cross(U[U.size()-2], p);
            ld sum = (US.empty()? 0 : US.back()) + c;
            US.push_back(sum);
        }

        if(i > n-3) {
            suf[i] = 0.0L;
        } else {
            ld area2 = US.back() - LS.back();
            if(area2 < 0) area2 = -area2;
            suf[i] = area2 / 2.0L;
        }
    }
    return suf;
}

int main(){
    int n = Cin();
    vector<P> pts(n);
    for (int i = 0; i < n; i++){
        pts[i].x = Cin(), pts[i].y = Cin();
    }
    sort(pts.begin(), pts.end(), [](const P &a, const P &b){
        if(a.x == b.x) return a.y < b.y;
        return a.x < b.x;
    });

    vector<ld> pre = getPrefixArea(pts);
    vector<ld> suf = getSuffixArea(pts);

    ld ans = pre[n-1];
    for (int i = 0; i < n-1; i++){
        if(pts[i].x < pts[i+1].x){
            ld tot = pre[i] + suf[i+1];
            if(tot < ans) ans = tot;
        }
    }
    Cout((ll)floor(ans + 0.5L));
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 12136
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct Point {
    ll X, Y;
    Point() : X(0), Y(0) {}
    Point(ll x, ll y) : X(x), Y(y) {}
};

ll cross(Point A, Point B) {
    return A.X * B.Y - A.Y * B.X;
}

ll Area(Point A, Point B, Point C) {
    B.X -= A.X, B.Y -= A.Y;
    C.X -= A.X, C.Y -= A.Y;
    return abs(cross(B,C));
}

int ccw(Point A, Point B, Point C) {
    B.X -= A.X, B.Y -= A.Y;
    C.X -= A.X, C.Y -= A.Y;
    if (cross(B,C) > 0) return 1;
    if (cross(B,C) < 0) return -1;
    return 0;
}

vector<ll> Calc(vector<Point> P) {
    int N = P.size();
    vector<ll> Ret(N+1);
    Ret[0] = Ret[1] = 0;
    vector<Point> upper, lower;
    upper.push_back(P[0]), lower.push_back(P[0]);
    rep(i,1,N) {
        Ret[i+1] = Ret[i];
        while(upper.size() >= 2 && ccw(upper[upper.size()-2],upper.back(),P[i]) == 1) {
            Ret[i+1] -= Area(upper[upper.size()-2], upper.back(), lower.back());
            upper.pop_back();
        }
        while(lower.size() >= 2 && ccw(lower[lower.size()-2],lower.back(),P[i]) == -1) {
            Ret[i+1] -= Area(lower[lower.size()-2], lower.back(), upper.back());
            lower.pop_back();
        }
        Ret[i+1] += Area(lower.back(), upper.back(), P[i]);
        lower.push_back(P[i]), upper.push_back(P[i]);
    }
    return Ret;
}

int main() {
    int N;
    cin >> N;
    vector<Point> P(N), RP(N);
    rep(i,0,N) {
        ll x, y;
        cin >> x >> y;
        P[i] = Point(x,y);
        RP[i] = Point(-x,y);
    }
    sort(ALL(P), [&](Point P1, Point P2){
        if (P1.X == P2.X) return P1.Y < P2.Y;
        return P1.X < P2.X;
    });
    sort(ALL(RP), [&](Point P1, Point P2){
        if (P1.X == P2.X) return P1.Y < P2.Y;
        return P1.X < P2.X;
    });
    auto A = Calc(P), RA = Calc(RP);
    reverse(ALL(RA));
    ll ANS = RA[0];
    rep(i,0,N-1) {
        if (P[i].X == P[i+1].X) continue;
        chmin(ANS, A[i+1]+RA[i+1]);
    }
    cout << (ANS+1)/2 << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 14204
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

using T = double;
const T eps = 1e-8;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, .0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, .0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * 2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw

    if (cross(b, c) < -eps)
        return -1; // cw

    if (dot(b, c) < 0)
        return 2; // c,a,b

    if (norm(b) < norm(c))
        return -2; // a,b,c

    return 0;      // a,c,b

}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), .0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), .0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return .0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, 0.) and eq(d2, 0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / 2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return .0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = .0;
        if (eq(f, .0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = .0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return .0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / 2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / 2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / 2.);
    res += b.r * b.r * (bth - sin(bth * 2) / 2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain

    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), .0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / 2., (a + b) / 2. + (b - a) * Point(0, 1));
    Line l2((b + c) / 2., (b + c) / 2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, 0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, 1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */

vector<double> Calc(vector<Point> P) {
    int N = P.size();
    vector<double> Ret(N+1);
    Ret[0] = Ret[1] = 0.0;
    vector<Point> upper, lower;
    upper.push_back(P[0]), lower.push_back(P[0]);
    rep(i,1,N) {
        Ret[i+1] = Ret[i];
        while(upper.size() >= 2 && ccw(upper[upper.size()-2],upper.back(),P[i]) == 1) {
            Ret[i+1] -= Area({upper[upper.size()-2], upper.back(), lower.back()});
            upper.pop_back();
        }
        while(lower.size() >= 2 && ccw(lower[lower.size()-2],lower.back(),P[i]) == -1) {
            Ret[i+1] -= Area({lower[lower.size()-2], lower.back(), upper.back()});
            lower.pop_back();
        }
        Ret[i+1] += Area({lower.back(), upper.back(), P[i]});
        lower.push_back(P[i]), upper.push_back(P[i]);
    }
    return Ret;
}

int main() {
    int N;
    cin >> N;
    vector<Point> P(N), RP(N);
    rep(i,0,N) {
        double x, y;
        cin >> x >> y;
        P[i] = Point(x,y);
        RP[i] = Point(-x,y);
    }
    sort(ALL(P), [&](Point P1, Point P2){
        if (eq(P1.real(),P2.real())) return P1.imag() < P2.imag();
        return P1.real() < P2.real();
    });
    sort(ALL(RP), [&](Point P1, Point P2){
        if (eq(P1.real(),P2.real())) return P1.imag() < P2.imag();
        return P1.real() < P2.real();
    });
    auto A = Calc(P), RA = Calc(RP);
    reverse(ALL(RA));
    double ANS = RA[0];
    rep(i,0,N-1) {
        if (eq(P[i].real(),P[i+1].real())) continue;
        chmin(ANS, A[i+1]+RA[i+1]);
    }
    cout << round(ANS) << endl;
}
accuracy: 0.1
time_ms: 10
memory_kb: 4288
final_rank: 16

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const long long INF = 15LL << 59;

class point {
public:
	long long x, y;
	point() : x(0), y(0) {}
	point(long long x_, long long y_) : x(x_), y(y_) {}
	point& operator+=(const point& p) { x += p.x; y += p.y; return *this; }
	point& operator-=(const point& p) { x -= p.x; y -= p.y; return *this; }
	point operator+(const point& p) const { return point(*this) += p; }
	point operator-(const point& p) const { return point(*this) -= p; }
	long long cross(const point& p) const { return x * p.y - y * p.x; }
};

vector<long long> subcalc(int N, const vector<point>& P) {
	vector<long long> ans = { 0 };
	long long area = 0;
	vector<int> s1, s2;
	for (int i = 0; i < N; i++) {
		if (s1.empty() || P[s1[s1.size() - 1]].y >= P[i].y) {
			while (s1.size() >= 2) {
				int v1 = s1[s1.size() - 1];
				int v2 = s1[s1.size() - 2];
				if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
					area -= P[v2].cross(P[v1]);
					s1.pop_back();
				} else {
					break;
				}
			}
			if (s1.size() >= 1) {
				area += P[s1[s1.size() - 1]].cross(P[i]);
			}
			s1.push_back(i);
		}
		while (s2.size() >= 1 && P[s2[s2.size() - 1]].y >= P[i].y) {
			if (s2.size() >= 2) {
				area -= P[s2[s2.size() - 2]].cross(P[s2[s2.size() - 1]]);
			}
			s2.pop_back();
		}
		while (s2.size() >= 2) {
			int v1 = s2[s2.size() - 1];
			int v2 = s2[s2.size() - 2];
			if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
				area -= P[v2].cross(P[v1]);
				s2.pop_back();
			} else {
				break;
			}
		}
		if (s2.size() >= 1) {
			area += P[s2[s2.size() - 1]].cross(P[i]);
		}
		s2.push_back(i);
		if (i == N - 1 || P[i].x != P[i + 1].x) {
			ans.push_back(area);
		}
	}
	return ans;
}

vector<long long> calc(int N, vector<point> P) {
	vector<long long> res1 = subcalc(N, P);
	for (int i = 0; i < N; i++) {
		P[i].y *= -1;
	}
	vector<long long> res2 = subcalc(N, P);
	vector<long long> res3(res1.size());
	for (int i = 0; i < int(res1.size()); i++) {
		res3[i] = res1[i] + res2[i];
	}
	return res3;
}

long long solve(int N, vector<point> P) {
	sort(P.begin(), P.end(), [&](const point& p1, const point& p2) {
		return p1.x != p2.x ? p1.x < p2.x : p1.y < p2.y;
	});
	vector<long long> res1 = calc(N, P);
	reverse(P.begin(), P.end());
	for (int i = 0; i < N; i++) {
		P[i].x *= -1;
		P[i].y *= -1;
	}
	vector<long long> res2 = calc(N, P);
	reverse(res2.begin(), res2.end());
	long long ans = INF;
	for (int i = 0; i < int(res1.size()); i++) {
		ans = min(ans, res1[i] + res2[i]);
	}
	return ans;
}

int main() {
	int N;
	cin >> N;
	vector<point> P(N);
	for (int i = 0; i < N; i++) {
		cin >> P[i].x >> P[i].y;
	}
	long long ans = solve(N, P);
	cout << (ans + 1) / 2 << endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 11160
final_rank: 4

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const long long INF = 7LL << 59;

class point {
public:
	long long x, y;
	point() : x(0), y(0) {}
	point(long long x_, long long y_) : x(x_), y(y_) {}
	point& operator+=(const point& p) { x += p.x; y += p.y; return *this; }
	point& operator-=(const point& p) { x -= p.x; y -= p.y; return *this; }
	point operator+(const point& p) const { return point(*this) += p; }
	point operator-(const point& p) const { return point(*this) -= p; }
	long long cross(const point& p) const { return x * p.y - y * p.x; }
};

vector<long long> subcalc(int N, const vector<point>& P) {
	vector<long long> ans = { 0 };
	long long area = 0;
	vector<int> s1, s2;
	for (int i = 0; i < N; i++) {
		if (s1.empty() || P[s1[s1.size() - 1]].y >= P[i].y) {
			while (s1.size() >= 2) {
				int v1 = s1[s1.size() - 1];
				int v2 = s1[s1.size() - 2];
				if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
					area -= P[v2].cross(P[v1]);
					s1.pop_back();
				} else {
					break;
				}
			}
			if (s1.size() >= 1) {
				area += P[s1[s1.size() - 1]].cross(P[i]);
			}
			s1.push_back(i);
		}
		while (s2.size() >= 1 && P[s2[s2.size() - 1]].y >= P[i].y) {
			if (s2.size() >= 2) {
				area -= P[s2[s2.size() - 2]].cross(P[s2[s2.size() - 1]]);
			}
			s2.pop_back();
		}
		while (s2.size() >= 2) {
			int v1 = s2[s2.size() - 1];
			int v2 = s2[s2.size() - 2];
			if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
				area -= P[v2].cross(P[v1]);
				s2.pop_back();
			} else {
				break;
			}
		}
		if (s2.size() >= 1) {
			area += P[s2[s2.size() - 1]].cross(P[i]);
		}
		s2.push_back(i);
		if (i == N - 1 || P[i].x != P[i + 1].x) {
			ans.push_back(area);
		}
	}
	return ans;
}

vector<long long> calc(int N, vector<point> P) {
	vector<long long> res1 = subcalc(N, P);
	for (int i = 0; i < N; i++) {
		P[i].y *= -1;
	}
	vector<long long> res2 = subcalc(N, P);
	vector<long long> res3(res1.size());
	for (int i = 0; i < int(res1.size()); i++) {
		res3[i] = res1[i] + res2[i];
	}
	return res3;
}

long long solve(int N, vector<point> P) {
	sort(P.begin(), P.end(), [&](const point& p1, const point& p2) {
		return p1.x != p2.x ? p1.x < p2.x : p1.y < p2.y;
	});
	vector<long long> res1 = calc(N, P);
	reverse(P.begin(), P.end());
	for (int i = 0; i < N; i++) {
		P[i].x *= -1;
		P[i].y *= -1;
	}
	vector<long long> res2 = calc(N, P);
	reverse(res2.begin(), res2.end());
	long long ans = INF;
	for (int i = 0; i < int(res1.size()); i++) {
		ans = min(ans, res1[i] + res2[i]);
	}
	return ans;
}

int main() {
	int N;
	cin >> N;
	vector<point> P(N);
	for (int i = 0; i < N; i++) {
		cin >> P[i].x >> P[i].y;
	}
	long long ans = solve(N, P);
	cout << (ans + 1) / 2 << endl;
	return 0;
}
accuracy: 0.1
time_ms: 10
memory_kb: 4504
final_rank: 17

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const long long INF = 3LL << 59;

class point {
public:
	long long x, y;
	point() : x(0), y(0) {}
	point(long long x_, long long y_) : x(x_), y(y_) {}
	point& operator+=(const point& p) { x += p.x; y += p.y; return *this; }
	point& operator-=(const point& p) { x -= p.x; y -= p.y; return *this; }
	point operator+(const point& p) const { return point(*this) += p; }
	point operator-(const point& p) const { return point(*this) -= p; }
	long long cross(const point& p) const { return x * p.y - y * p.x; }
};

#include <string>

string to_string(const vector<int>& arr) {
	string res = "[";
	for (int i = 0; i < arr.size(); i++) {
		if (i != 0) {
			res += ", ";
		}
		res += to_string(arr[i]);
	}
	res += "]";
	return res;
}

vector<long long> subcalc(int N, const vector<point>& P) {
	vector<long long> ans = { 0 };
	long long area = 0;
	vector<int> s1, s2;
	for (int i = 0; i < N; i++) {
		if (s1.empty() || P[s1[s1.size() - 1]].y >= P[i].y) {
			while (s1.size() >= 2) {
				int v1 = s1[s1.size() - 1];
				int v2 = s1[s1.size() - 2];
				if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
					area -= P[v2].cross(P[v1]);
					s1.pop_back();
				} else {
					break;
				}
			}
			if (s1.size() >= 1) {
				area += P[s1[s1.size() - 1]].cross(P[i]);
			}
			s1.push_back(i);
		}
		while (s2.size() >= 1 && P[s2[s2.size() - 1]].y >= P[i].y) {
			if (s2.size() >= 2) {
				area -= P[s2[s2.size() - 2]].cross(P[s2[s2.size() - 1]]);
			}
			s2.pop_back();
		}
		while (s2.size() >= 2) {
			int v1 = s2[s2.size() - 1];
			int v2 = s2[s2.size() - 2];
			if ((P[v1] - P[i]).cross(P[v2] - P[i]) >= 0) {
				area -= P[v2].cross(P[v1]);
				s2.pop_back();
			} else {
				break;
			}
		}
		if (s2.size() >= 1) {
			area += P[s2[s2.size() - 1]].cross(P[i]);
		}
		s2.push_back(i);
		if (i == N - 1 || P[i].x != P[i + 1].x) {
			ans.push_back(area);
		}
	}
	return ans;
}

vector<long long> calc(int N, vector<point> P) {
	vector<long long> res1 = subcalc(N, P);
	for (int i = 0; i < N; i++) {
		P[i].y *= -1;
	}
	vector<long long> res2 = subcalc(N, P);
	vector<long long> res3(res1.size());
	for (int i = 0; i < int(res1.size()); i++) {
		res3[i] = res1[i] + res2[i];
	}
	return res3;
}

long long solve(int N, vector<point> P) {
	sort(P.begin(), P.end(), [&](const point& p1, const point& p2) {
		return p1.x != p2.x ? p1.x < p2.x : p1.y < p2.y;
	});
	vector<long long> res1 = calc(N, P);
	reverse(P.begin(), P.end());
	for (int i = 0; i < N; i++) {
		P[i].x *= -1;
		P[i].y *= -1;
	}
	vector<long long> res2 = calc(N, P);
	reverse(res2.begin(), res2.end());
	long long ans = INF;
	for (int i = 0; i < int(res1.size()); i++) {
		ans = min(ans, res1[i] + res2[i]);
	}
	return ans;
}

int main() {
	int N;
	cin >> N;
	vector<point> P(N);
	for (int i = 0; i < N; i++) {
		cin >> P[i].x >> P[i].y;
	}
	long long ans = solve(N, P);
	cout << (ans + 1) / 2 << endl;
	return 0;
}
accuracy: 0.1
time_ms: 10
memory_kb: 4504
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define sz(A) ((ll)A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N;cin>>N;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    vi X;
    REP(i,N)X.emplace_back(A[i].first);
    sort(ALL(X));
    X.erase(unique(ALL(X)),X.end());
    vi D(sz(X),1e18),U(sz(X),-1e18);
    REP(i,N){
        int x=LB(X,A[i].first);
        D[x]=min(D[x],A[i].second);
        U[x]=max(U[x],A[i].second);
    }
    N=X.size();

    vi ans1(N+1),ans2(N+1);
    auto f=[](pi a,pi b){
        return a.first*b.second-a.second*b.first;
    };
    {
        stack<pi>upper,lower;
        __int128 area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                area+=f(q,p);
                lower.emplace(p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans1[i+1]=area;
            assert(area>=0);
        }
    }
    {
        REP(i,N)X[i]=-X[i];
        reverse(ALL(X));
        reverse(ALL(D));
        reverse(ALL(U));
        stack<pi>upper,lower;
        __int128 area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                lower.emplace(p);
                area+=f(q,p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            assert(area>=0);
            ans2[i+1]=area;
        }
    }
    ll ans=9e18;
    REP(i,N+1)ans=min(ans,ans1[i]+ans2[N-i]);
    cout<<(ans+1)/2<<endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 10056
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define sz(A) ((ll)A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N;cin>>N;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    vi X;
    REP(i,N)X.emplace_back(A[i].first);
    sort(ALL(X));
    X.erase(unique(ALL(X)),X.end());
    vi D(sz(X),1e18),U(sz(X),-1e18);
    REP(i,N){
        int x=LB(X,A[i].first);
        D[x]=min(D[x],A[i].second);
        U[x]=max(U[x],A[i].second);
    }
    N=X.size();

    vi ans1(N+1),ans2(N+1);
    auto f=[](pi a,pi b){
        return a.first*b.second-a.second*b.first;
    };
    {
        stack<pi>upper,lower;
        __int128 area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                area+=f(q,p);
                lower.emplace(p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans1[i+1]=area;
        }
    }
    {
        REP(i,N)X[i]=-X[i];
        reverse(ALL(X));
        reverse(ALL(D));
        reverse(ALL(U));
        stack<pi>upper,lower;
        __int128 area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                lower.emplace(p);
                area+=f(q,p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans2[i+1]=area;
        }
    }
    ll ans=5e18;
    REP(i,N+1)ans=min(ans,ans1[i]+ans2[N-i]);
    cout<<(ans+1)/2<<endl;
    return 0;
}
accuracy: 0.1
time_ms: 10
memory_kb: 3788
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define sz(A) ((ll)A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N;cin>>N;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    vi X;
    REP(i,N)X.emplace_back(A[i].first);
    sort(ALL(X));
    X.erase(unique(ALL(X)),X.end());
    vi D(sz(X),1e18),U(sz(X),-1e18);
    REP(i,N){
        int x=LB(X,A[i].first);
        D[x]=min(D[x],A[i].second);
        U[x]=max(U[x],A[i].second);
    }
    N=X.size();

    vi ans1(N+1),ans2(N+1);
    auto f=[](pi a,pi b){
        return a.first*b.second-a.second*b.first;
    };
    {
        stack<pi>upper,lower;
        ll area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                area+=f(q,p);
                lower.emplace(p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans1[i+1]=area;
        }
    }
    {
        REP(i,N)X[i]=-X[i];
        reverse(ALL(X));
        reverse(ALL(D));
        reverse(ALL(U));
        stack<pi>upper,lower;
        ll area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                lower.emplace(p);
                area+=f(q,p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans2[i+1]+=area;
        }
    }
    ll ans=5e18;
    REP(i,N+1)ans=min(ans,ans1[i]+ans2[N-i]);
    cout<<(ans+1)/2<<endl;
    return 0;
}
accuracy: 0.1
time_ms: 10
memory_kb: 3928
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define sz(A) ((ll)A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N;cin>>N;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    vi X;
    REP(i,N)X.emplace_back(A[i].first);
    sort(ALL(X));
    X.erase(unique(ALL(X)),X.end());
    vi D(sz(X),1e18),U(sz(X),-1e18);
    REP(i,N){
        int x=LB(X,A[i].first);
        D[x]=min(D[x],A[i].second);
        U[x]=max(U[x],A[i].second);
    }
    N=X.size();

    vi ans1(N+1),ans2(N+1);
    auto f=[](pi a,pi b){
        return a.first*b.second-a.second*b.first;
    };
    {
        stack<pi>upper,lower;
        ll area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                area+=f(q,p);
                lower.emplace(p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans1[i+1]=area;
        }
    }
    {
        REP(i,N)X[i]=-X[i];
        reverse(ALL(X));
        reverse(ALL(D));
        reverse(ALL(U));
        stack<pi>upper,lower;
        ll area=0;
        upper.emplace(pi(X[0],U[0]));
        lower.emplace(pi(X[0],D[0]));
        FOR(i,1,N){
            area-=f(lower.top(),upper.top());
            while(sz(upper)>1){
                auto p=upper.top();upper.pop();
                auto q=upper.top();
                area-=f(p,q);
                if(f(pi(p.first-q.first,p.second-q.second),pi(X[i]-q.first,U[i]-q.second))>=0)continue;
                upper.emplace(p);
                area+=f(p,q);
                break;
            }
            area+=f(pi(X[i],U[i]),upper.top());
            upper.emplace(pi(X[i],U[i]));
            while(sz(lower)>1){
                auto p=lower.top();lower.pop();
                auto q=lower.top();
                area-=f(q,p);
                if(f(pi(X[i]-q.first,D[i]-q.second),pi(p.first-q.first,p.second-q.second))>=0)continue;
                lower.emplace(p);
                area+=f(q,p);
                break;
            }
            area+=f(lower.top(),pi(X[i],D[i]));
            lower.emplace(pi(X[i],D[i]));
            area+=f(pi(X[i],D[i]),pi(X[i],U[i]));
            ans2[i+1]+=area;
        }
    }
    //REP(i,N+1)cout<<ans1[i]<<" ";cout<<endl;
    //REP(i,N+1)cout<<ans2[i]<<" ";cout<<endl;
    ll ans=1e18;
    REP(i,N+1)ans=min(ans,ans1[i]+ans2[N-i]);
    cout<<(ans+1)/2<<endl;
    return 0;
}
accuracy: 0.1
time_ms: 10
memory_kb: 3912
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
#define all(p) p.begin(),p.end()
const int mod=998244353;

int main(){
	int N;
	cin>>N;
	set<ll> s;
	vector<pair<ll,ll>> p(N);
	rep(i,0,N){
		cin>>p[i].first>>p[i].second;
		s.insert(p[i].first);
	}
	sort(all(p));
	map<int,int> m;
	vector<ll> order={167};
	int len=1;
	for(auto x:s) m[x]=len,len++,order.push_back(x);
	order.push_back(167);
	vector<ll> U(len+1,-INF),D(len+1,-INF);
	rep(i,0,N){
		int a=m[p[i].first];
		chmax(U[a],p[i].second);
		chmax(D[a],-p[i].second);
	}
	auto f=[&]()->vector<ll>{
		vector<ll> ans(len+1);
		vector<int> p(len+1);
		int k=0;
		rep(i,1,len){
			ans[i]=ans[i-1];
			if(k==0){
				p[k]=i;
				k++;
			}else if(k==1){
				p[k]=i;
				k++;
				ans[i]+=abs(order[i]-order[i-1])*(U[i]+U[i-1]);
			}else{
				while(2<=k){
					int a=p[k-2],b=p[k-1],c=i;
					//U[b]<=(U[a]*dist(b,c)+U[c]*dist(a,b))/dist(a,c);
					if(U[b]*abs(order[a]-order[c])<=U[a]*abs(order[b]-order[c])+U[c]*abs(order[b]-order[a])){
						ans[i]-=abs(order[b]-order[a])*(U[a]+U[b]);
						k--;
					}
					else break;
				}
				p[k]=i;
				ans[i]+=abs(order[i]-order[p[k-1]])*(U[i]+U[p[k-1]]);
				k++;
			}
		}
		return ans;
	};
	vector<vector<ll>> area(4);
	rep(i,0,2){
		rep(j,0,2){
			area[i*2+j]=f();
			swap(U,D);
		}
		reverse(all(order));
		reverse(all(U));
		reverse(all(D));
	}
	ll ans=area[0][len-1]+area[1][len-1];
	rep(i,1,len-1){
		chmin(ans,area[0][i]+area[1][i]+area[2][len-1-i]+area[3][len-1-i]);
	}
	cout<<(1+ans)/2<<"\n";
}
accuracy: 1
time_ms: 80
memory_kb: 19928
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
#define all(p) p.begin(),p.end()
const int mod=998244353;

int main(){
	int N;
	cin>>N;
	set<ll> s;
	vector<pair<ll,ll>> p(N);
	rep(i,0,N){
		cin>>p[i].first>>p[i].second;
		s.insert(p[i].first);
	}
	sort(all(p));
	map<int,int> m;
	vector<ll> order={167};
	int len=1;
	for(auto x:s) m[x]=len,len++,order.push_back(x);
	order.push_back(167);
	vector<ll> U(len+1,-INF),D(len+1,-INF);
	rep(i,0,N){
		int a=m[p[i].first];
		chmax(U[a],p[i].second);
		chmax(D[a],-p[i].second);
	}
	auto f=[&]()->vector<ll>{
		vector<ll> ans(len+1);
		vector<int> p(len+1);
		int k=0;
		rep(i,1,len){
			ans[i]=ans[i-1];
			if(k==0){
				p[k]=i;
				k++;
			}else if(k==1){
				p[k]=i;
				k++;
				ans[i]+=abs(order[i]-order[i-1])*(U[i]+U[i-1]);
			}else{
				while(2<=k){
					int a=p[k-2],b=p[k-1],c=i;
					//U[b]<=(U[a]*dist(b,c)+U[c]*dist(a,b))/dist(a,c);
					if(U[b]*abs(order[a]-order[c])<=U[a]*abs(order[b]-order[c])+U[c]*abs(order[b]-order[a])){
						ans[i]-=abs(order[b]-order[a])*(U[a]+U[b]);
						k--;
					}
					else break;
				}
				p[k]=i;
				ans[i]+=abs(order[i]-order[p[k-1]])*(U[i]+U[p[k-1]]);
				k++;
			}
		}
		return ans;
	};
	vector<vector<ll>> area(4);
	rep(i,0,2){
		rep(j,0,2){
			area[i*2+j]=f();
			swap(U,D);
		}
		reverse(all(order));
		reverse(all(U));
		reverse(all(D));
	}
	ll ans=(1ll<<62);
	rep(i,0,len){
		chmin(ans,area[0][i]+area[1][i]+area[2][len-1-i]+area[3][len-1-i]);
	}
	cout<<(1+ans)/2<<"\n";
}
accuracy: 0.1
time_ms: 10
memory_kb: 5856
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    auto calc = [&](vector<Vec> pts) {
        sort(all(pts), [&](auto& p1, auto& p2) {
            if (p1.real() == p2.real()) return p1.imag() < p2.imag();
            return p1.real() < p2.real();
        });
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        lower.push_back(pts[0]);
        upper.push_back(pts[0]);
        area[0] = area[1] = 0;
        ll a = 0;
        for (int i = 1; i < N; ) {
            int j = i;
            while (j < N && pts[i].real() == pts[j].real()) {
                while (lower.size() >= 2 && leq(cross(lower.back()-lower[lower.size()-2], pts[j]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && leq(0, cross(upper.back()-upper[upper.size()-2], pts[j]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[j], lower.back()-pts[j]));
                upper.push_back(pts[j]);
                lower.push_back(pts[j]);
                ++j;
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    rep(i,0,N) pts[i] = Vec(-pts[i].real(), pts[i].imag());
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 10316
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    auto calc = [&](vector<Vec> pts) {
        sort(all(pts), [&](auto& p1, auto& p2) {
            if (p1.real() == p2.real()) p1.imag() < p2.imag();
            return p1.real() < p2.real();
        });
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        lower.push_back(pts[0]);
        upper.push_back(pts[0]);
        area[0] = area[1] = 0;
        ll a = 0;
        for (int i = 1; i < N; ) {
            int j = i;
            while (j < N && pts[i].real() == pts[j].real()) {
                while (lower.size() >= 2 && leq(cross(lower.back()-lower[lower.size()-2], pts[j]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && leq(0, cross(upper.back()-upper[upper.size()-2], pts[j]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[j], lower.back()-pts[j]));
                upper.push_back(pts[j]);
                lower.push_back(pts[j]);
                ++j;
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    rep(i,0,N) pts[i] = Vec(-pts[i].real(), pts[i].imag());
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 0.675
time_ms: 20
memory_kb: 7120
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    auto calc = [&](vector<Vec> pts) {
        sort(all(pts), [&](auto& p1, auto& p2) { return p1.real() < p2.real(); });
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        if (pts[0].real() < pts[1].real()) {
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[0]);
            upper.push_back(pts[1]);
        } else {
            if (pts[0].imag() < pts[1].imag()) swap(pts[0], pts[1]);
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[1]);
            upper.push_back(pts[0]);
        }
        area[0] = area[1] = area[2] = 0;
        ll a = 0;
        for (int i = 2; i < N; ) {
            int j = i;
            while (j < N && pts[i].real() == pts[j].real()) {
                while (lower.size() >= 2 && leq(cross(lower.back()-lower[lower.size()-2], pts[j]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && leq(0, cross(upper.back()-upper[upper.size()-2], pts[j]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[j], lower.back()-pts[j]));
                upper.push_back(pts[j]);
                lower.push_back(pts[j]);
                ++j;
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    rep(i,0,N) pts[i] = Vec(-pts[i].real(), pts[i].imag());
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 0.675
time_ms: 20
memory_kb: 7040
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    auto calc = [&](vector<Vec> pts) {
        sort(all(pts), [&](auto& p1, auto& p2) { return p1.real() < p2.real(); });
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        if (pts[0].real() < pts[1].real()) {
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[0]);
            upper.push_back(pts[1]);
        } else {
            if (pts[0].imag() < pts[1].imag()) swap(pts[0], pts[1]);
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[1]);
            upper.push_back(pts[0]);
        }
        area[0] = area[1] = area[2] = 0;
        ll a = 0;
        for (int i = 2; i < N; ) {
            int j = i;
            while (j < N && pts[i].real() == pts[j].real()) {
                while (lower.size() >= 2 && lt(cross(lower.back()-lower[lower.size()-2], pts[j]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && lt(0, cross(upper.back()-upper[upper.size()-2], pts[j]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[j], lower.back()-pts[j]));
                upper.push_back(pts[j]);
                lower.push_back(pts[j]);
                ++j;
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    rep(i,0,N) pts[i] = Vec(-pts[i].real(), pts[i].imag());
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 0.6
time_ms: 20
memory_kb: 7016
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    sort(all(pts), [&](auto& p1, auto& p2) {
        return p1.real() < p2.real();
    });

    auto calc = [&](vector<Vec> pts) {
        sort(all(pts), [&](auto& p1, auto& p2) { return p1.real() < p2.real(); });
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        if (pts[0].real() < pts[1].real()) {
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[0]);
            upper.push_back(pts[1]);
        } else {
            if (pts[0].imag() < pts[1].imag()) swap(pts[0], pts[1]);
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[1]);
            upper.push_back(pts[0]);
        }
        area[0] = area[1] = area[2] = 0;
        ll a = 0;
        for (int i = 2; i < N; ) {
            int j = i+1;
            while (j < N && pts[i].real() == pts[j].real()) ++j;
            rep(k,i,j) {
                while (lower.size() >= 2 && lt(cross(lower.back()-lower[lower.size()-2], pts[k]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && lt(0, cross(upper.back()-upper[upper.size()-2], pts[k]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[k], lower.back()-pts[k]));
                upper.push_back(pts[k]);
                lower.push_back(pts[k]);
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    rep(i,0,N) pts[i] = Vec(-pts[i].real(), pts[i].imag());
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 0.6
time_ms: 20
memory_kb: 7156
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

using T = ll;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-10;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// -1: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

std::vector<Vec> convex_hull(std::vector<Vec>& pts) {
    int n = pts.size();
    if (n == 1) return pts;
    std::sort(pts.begin(), pts.end(), [](const Vec& v1, const Vec& v2) {
        return (v1.imag() != v2.imag()) ? (v1.imag() < v2.imag()) : (v1.real() < v2.real());
    });
    int k = 0; // the number of vertices in the convex hull
    std::vector<Vec> ch(2 * n);
    // right
    for (int i = 0; i < n; ++i) {
        while (k > 1 && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    int t = k;
    // left
    for (int i = n - 2; i >= 0; --i) {
        while (k > t && lt(cross(ch[k-1] - ch[k-2], pts[i] - ch[k-1]), 0)) --k;
        ch[k++] = pts[i];
    }
    ch.resize(k - 1);
    return ch;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<Vec> pts(N);
    for (auto& p : pts) cin >> p;

    if (N <= 2) {
        cout << 0 << endl;
        return 0;
    }

    sort(all(pts), [&](auto& p1, auto& p2) {
        return p1.real() < p2.real();
    });

    auto calc = [&](vector<Vec> pts) {
        vector<ll> area(N+1, 4e18);
        vector<Vec> lower, upper;
        if (pts[0].real() < pts[1].real()) {
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[0]);
            upper.push_back(pts[1]);
        } else {
            if (pts[0].imag() < pts[1].imag()) swap(pts[0], pts[1]);
            lower.push_back(pts[0]);
            lower.push_back(pts[1]);
            upper.push_back(pts[1]);
            upper.push_back(pts[0]);
        }
        area[0] = area[1] = area[2] = 0;
        ll a = 0;
        for (int i = 2; i < N; ) {
            int j = i+1;
            while (j < N && pts[i].real() == pts[j].real()) ++j;
            rep(k,i,j) {
                while (lower.size() >= 2 && lt(cross(lower.back()-lower[lower.size()-2], pts[k]-lower.back()), 0)) {
                    a -= abs(cross(lower[lower.size()-2]-lower.back(), upper.back()-lower.back()));
                    lower.pop_back();
                }
                while (upper.size() >= 2 && lt(0, cross(upper.back()-upper[upper.size()-2], pts[k]-upper.back()))) {
                    a -= abs(cross(upper[upper.size()-2]-upper.back(), lower.back()-upper.back()));
                    upper.pop_back();
                }
                a += abs(cross(upper.back()-pts[k], lower.back()-pts[k]));
                upper.push_back(pts[k]);
                lower.push_back(pts[k]);
            }
            area[j] = a;
            i = j;
        }
        return area;
    };

    auto left = calc(pts);
    reverse(all(pts));
    auto right = calc(pts);
    ll ans = 4e18;
    rep(i,0,N+1) {
        chmin(ans, (left[i]+right[N-i]+1)/2);
    }
    cout << ans << endl;
}
accuracy: 0.325
time_ms: 20
memory_kb: 7048
final_rank: 12