Problem:
K - Autumn Triangle
Time Limit: 2 sec
問題文
この問題はPython3でのACが確認されていないため、C++などの高速な言語の使用をおすすめします。
「春の大三角」、「夏の大三角」、「冬の大三角」と呼ばれる星群はありますが、「秋の大三角」と呼ばれる星群はありません。そこで、tupc君は秋の星空から3つの星を選んで「秋の大三角」を作ることにしました。
秋の星空は2次元平面で表され、$N$個の星が散りばめられています。$i$番目の星の座標は$(X_i, Y_i)$で、明るさは$A_i$です。
$N$個の星から3つ選んで作ることができる三角形はたくさんありますが、tupc君はその中でも最も美しいものに興味があります。
星$i,j,k$からなる三角形の美しさは次の式で表されます。
$$2A_iA_jA_k \times (\text{三角形$ijk$の面積})$$
星$i$を含む三角形のうち、tupc君が作ることのできる最も美しい三角形の美しさを各$i = 1, \dots, N$について求めてください。 答えは必ず整数になります。
制約
$3 \leq N \leq 2000$
$1 \leq A_i \leq 300$
$|X_i|, |Y_i| \leq 10^5$
$i \neq j$ ならば $X_i \neq X_j$ または $Y_i \neq Y_j$
同一直線上にない3点が少なくとも1組存在する
入力はすべて整数
入力
$N$
$A_1\quad A_2 \quad \dots\quad A_N$
$X_1\quad Y_1$
$X_2\quad Y_2$
$\vdots$
$X_N\quad Y_N$
出力
$N$行出力せよ。
$i$行目には星$i$を含む三角形の美しさのうち最大のものを出力せよ。
入力例1
7
5
9
8
1
3
8
2
0
0
2
1
-2
-1
4
5
-5
6
-4
-5
6
-4
出力例1
5880
15552
7344
2352
15552
15552
7776

Submitted solutions:

code_snippet: // AOJ #3264 Autumn Triangle
// 2025.4.15

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

#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');
}

ll cr(const Vec &a, const Vec &b) { return (conj(a) * b).imag(); }

vector<Vec> getHull(vector<Vec> pts) {
    int n = pts.size();
    sort(pts.begin(), pts.end(), [](const Vec &p, const Vec &q) {
        return (p.imag() == q.imag()) ? (p.real() < q.real()) : (p.imag() < q.imag());
    });
    vector<Vec> ch(2 * n);
    int k = 0;
    for (int i = 0; i < n; i++) {
        while (k >= 2 && cr(ch[k-1] - ch[k-2], pts[i] - ch[k-1]) <= 0) k--;
        ch[k++] = pts[i];
    }
    int t = k;
    for (int i = n - 2; i >= 0; i--) {
        while (k > t && cr(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(){
    int N = Cin();
    vector<ll> A(N);
    for (int i = 0; i < N; i++) A[i] = Cin();
    vector<Vec> P(N);
    for (int i = 0; i < N; i++){
        int x = Cin(), y = Cin();
        P[i] = {x, y};
    }

    for (int i = 0; i < N; i++){
        vector<Vec> Q;
        Q.reserve(N);
        for (int j = 0; j < N; j++) Q.push_back((j == i) ? Vec(0,0) : (P[j] - P[i]) * (ll)A[j]);
        vector<Vec> ch = getHull(Q);
        int M = ch.size();
        ll best = 0;
        if(M == 0){ pc('0'), pc('\n'); continue; }
        int k = 0;
        for (int j = 0; j < M; j++){
            k = max(k, j);
            while ( cr(ch[j], ch[k % M]) < cr(ch[j], ch[(k+1) % M]) ) k++;
            best = max(best, cr(ch[j], ch[k % M]));
        }
        Cout(A[i] * best);
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3548
final_rank: 3

code_snippet: // AOJ #3264 Autumn Triangle
// 2025.4.15

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

#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 Point { ll x, y; };
struct Star { int A, x, y; };
inline ll cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
inline Point sub(const Point &a, const Point &b) { return {a.x - b.x, a.y - b.y}; }
inline int quadrant(const Point &p) { return (p.y > 0 || (p.y == 0 && p.x >= 0)) ? 0 : 1; }

struct PolarCmp {
    bool operator()(const Point &a, const Point &b) const {
        int qa = quadrant(a), qb = quadrant(b);
        if (qa != qb) return qa < qb;
        ll cp = cross(a, b);
        if(cp == 0) return (a.x * a.x + a.y * a.y) < (b.x * b.x + b.y * b.y);
        return cp > 0;
    }
};

vector<Point> convexHull(vector<Point> pts) {
    if (pts.size() <= 1) return pts;
    sort(pts.begin(), pts.end(), [](const Point &a, const Point &b) {
        return (a.y == b.y) ? (a.x < b.x) : (a.y < b.y);
    });
    vector<Point> lower;
    for (auto &p : pts) {
        while (lower.size() >= 2 &&
               cross(sub(lower.back(), lower[lower.size()-2]), sub(p, lower.back())) <= 0)
            lower.pop_back();
        lower.push_back(p);
    }
    vector<Point> upper;
    for (int i = pts.size()-1; i >= 0; i--) {
        while (upper.size() >= 2 &&
               cross(sub(upper.back(), upper[upper.size()-2]), sub(pts[i], upper.back())) <= 0)
            upper.pop_back();
        upper.push_back(pts[i]);
    }
    lower.pop_back();
    upper.pop_back();
    lower.insert(lower.end(), upper.begin(), upper.end());
    return lower;
}

ll maxCross(const vector<Point> &ch) {
    int M = ch.size();
    ll best = 0;
    int k = 0;
    for (int j = 0; j < M; j++) {
        k = max(k, j);
        while ( cross(ch[j], ch[(k+1)%M]) > cross(ch[j], ch[k%M]) ) k++;
        best = max(best, cross(ch[j], ch[k%M]));
    }
    return best;
}

int main(){
    int N = Cin();
    vector<Star> stars(N);
    for (int i = 0; i < N; i++) stars[i].A = Cin();
    vector<Point> P(N);
    for (int i = 0; i < N; i++){
        stars[i].x = Cin(), stars[i].y = Cin();
        P[i] = {stars[i].x, stars[i].y};
    }

    for (int i = 0; i < N; i++){
        vector<Point> Q;
        Q.reserve(N);
        for (int j = 0; j < N; j++){
            if(j == i) continue;
            ll dx = P[j].x - P[i].x;
            ll dy = P[j].y - P[i].y;
            dx *= stars[j].A;
            dy *= stars[j].A;
            Q.push_back({dx, dy});
        }
        sort(Q.begin(), Q.end(), PolarCmp());
        vector<Point> ch = convexHull(Q);
        ll best = maxCross(ch);
        Cout(stars[i].A * best);
    }
    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 3516
final_rank: 9

code_snippet: // AOJ #3264 Autumn Triangle
// 2025.4.15

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

#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');
}

ll cr(const Vec &a, const Vec &b) {
    return (conj(a) * b).imag();
}

vector<Vec> getHull(vector<Vec> pts) {
    int n = pts.size();
    sort(pts.begin(), pts.end(), [](const Vec &p, const Vec &q) {
        return (p.imag() == q.imag()) ? (p.real() < q.real()) : (p.imag() < q.imag());
    });
    vector<Vec> ch(2 * n);
    int k = 0;
    for (int i = 0; i < n; i++) {
        while (k >= 2 && cr(ch[k-1] - ch[k-2], pts[i] - ch[k-1]) <= 0) k--;
        ch[k++] = pts[i];
    }
    int t = k;
    for (int i = n - 2; i >= 0; i--) {
        while (k > t && cr(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(){
    int N = Cin();
    vector<ll> A(N);
    for (int i = 0; i < N; i++) A[i] = Cin();
    vector<Vec> P(N);
    for (int i = 0; i < N; i++){
        int x = Cin(), y = Cin();
        P[i] = {x, y};
    }

    for (int i = 0; i < N; i++){
        vector<Vec> Q;
        Q.reserve(N);
        for (int j = 0; j < N; j++) Q.push_back((j == i) ? Vec(0,0) : (P[j] - P[i]) * (ll)A[j]);
        vector<Vec> ch = getHull(Q);
        int M = ch.size();
        ll best = 0;
        if(M == 0){
            pc('0'), pc('\n');
            continue;
        }
        int k = 0;
        for (int j = 0; j < M; j++){
            k = max(k, j);
            while ( cr(ch[j], ch[k % M]) < cr(ch[j], ch[(k+1) % M]) ) k++;
            best = max(best, cr(ch[j], ch[k % M]));
        }
        Cout(A[i] * best);
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3620
final_rank: 7

code_snippet: // AOJ #3264 Autumn Triangle
// 2025.4.15

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

ll cr(const Vec &a, const Vec &b) {
    return (conj(a) * b).imag();
}

vector<Vec> getHull(vector<Vec> pts) {
    int n = pts.size();
    sort(pts.begin(), pts.end(), [](const Vec &p, const Vec &q) {
        return (p.imag() == q.imag()) ? (p.real() < q.real()) : (p.imag() < q.imag());
    });
    vector<Vec> ch(2 * n);
    int k = 0;
    for (int i = 0; i < n; i++) {
        while (k >= 2 && cr(ch[k-1] - ch[k-2], pts[i] - ch[k-1]) <= 0) k--;
        ch[k++] = pts[i];
    }
    int t = k;
    for (int i = n - 2; i >= 0; i--) {
        while (k > t && cr(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::sync_with_stdio(0);
    cin.tie(0);

    int N;
    cin >> N;
    vector<ll> A(N);
    for (int i = 0; i < N; i++) cin >> A[i];
    vector<Vec> P(N);
    for (int i = 0; i < N; i++){
        int x, y;
        cin >> x >> y;
        P[i] = {x, y};
    }

    for (int i = 0; i < N; i++){
        vector<Vec> Q;
        Q.reserve(N);
        for (int j = 0; j < N; j++) Q.push_back((j == i) ? Vec(0,0) : (P[j] - P[i]) * (ll)A[j]);
        vector<Vec> ch = getHull(Q);
        int M = ch.size();
        ll best = 0;
        if(M == 0){
            cout << 0 << endl;
            continue;
        }
        int k = 0;
        for (int j = 0; j < M; j++){
            k = max(k, j);
            while ( cr(ch[j], ch[k % M]) < cr(ch[j], ch[(k+1) % M]) ) k++;
            best = max(best, cr(ch[j], ch[k % M]));
        }
        cout << A[i] * best << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3600
final_rank: 4

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

// 整数幾何
typedef ll Integer;
const Integer eps = 0;
inline constexpr int sgn(Integer a, Integer b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline constexpr int arg_type(Integer x, Integer y) { return y < 0 ? 2 : x < 0 ? 1 : 0; }
struct Point {
    Integer x, y;
    constexpr Point(Integer x = 0, Integer y = 0) : x(x), y(y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr Point &operator*=(const Integer &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const Integer &k) { return Point(x * k, y * k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }
    constexpr Integer dot(const Point &r) const { return x * r.x + y * r.y; }
    constexpr Integer cross(const Point &r) const { return x * r.y - y * r.x; }
    constexpr Integer norm2() const { return x*x + y*y; }
    // 比較関数
    constexpr bool lex_comp(const Point &r) const {
        return sgn(x, r.x) < 0 || (sgn(x, r.x) == 0 and sgn(y, r.y) < 0);
    }
    constexpr bool arg_comp(const Point &r) const {
        int L = arg_type(x, y), R = arg_type(r.x, r.y);
        if (L != R) return L < R;
        Integer crs = (*this).cross(r);
        if (crs == 0) return abs(x) + abs(y) < abs(r.x) + abs(r.y);
        else return crs > 0;
    }
    // IO
    friend ostream &operator<<(ostream &os, Point &p) { return os << p.x << " " << p.y; }
    friend istream &operator>>(istream &is, Point &p) { is >> p.x >> p.y; return (is); }
};

Integer dot(Point a, Point b) { return a.dot(b); }
Integer cross(Point a, Point b) { return a.cross(b); }
int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1; // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1; // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2; // c,a,b 一直線上
    if (sgn(c.norm2() - b.norm2()) == 1) return -2; // a,b,c 一直線上
    return 0; // a,c,b 一直線上
}

vector<Point> convex_hull(vector<Point> ps, bool ONSEG = false) {
    int n = (int)ps.size();
    if (n <= 2) return ps;
    sort(ps.begin(), ps.end(), [&](auto i, auto j) {
        return i.lex_comp(j);
    });
    int k = 0; // 凸包の頂点数
    vector<Point> qs(2*n); // 構築中の凸包

    auto check = [&](int c) {
        return ONSEG ? c == -1 : c <= 0;
    };
    // Build lower hull
    for (int i = 0; i < n; ++i) {
        while (k >= 2 and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }
    // Build upper hull
    for (int i = n - 2, t = k + 1; i >= 0; --i) {
        while (k >= t and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }

    qs.resize(k-1);
    return qs;
}

// 原点と他2点を選んで三角形の面積を最大化(2倍の値で返す)
// AOJ 3264
Integer calc_maximum_triangle(vector<Point> ps) {
    ps = convex_hull(ps);
    int n = (int)ps.size();
    if (n <= 2) return 0;
    for (int i = 0; i < n; ++i) {
        ps.push_back(ps[i]);
    }
    Integer res = 0;
    int r = 0;
    for (int l = 0; l < n; ++l) {
        while (cross(ps[l], ps[r]) < cross(ps[l], ps[r+1])) r += 1;
        res = max(res, cross(ps[l], ps[r]));
        if (l == r) r += 1;
    }
    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<Point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i];
    }

    // fix i && p[i] -> (0,0)
    // S = a_j * a_k * |x_j * y_k - x_k * y_j|
    for (int i = 0; i < n; ++i) {
        vector<Point> qs(n-1);
        for (int j = 0, k = 0; j < n; ++j) {
            if (i == j) continue;
            qs[k++] = (p[j]-p[i]) * a[j];
        }
        cout << calc_maximum_triangle(qs)*a[i] << "\n";
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3504
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

// 整数幾何
typedef ll Integer;
const Integer eps = 0;
inline constexpr int sgn(Integer a, Integer b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline constexpr int arg_type(Integer x, Integer y) { return y < 0 ? 2 : x < 0 ? 1 : 0; }
struct Point {
    Integer x, y;
    constexpr Point(Integer x = 0, Integer y = 0) : x(x), y(y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr Point &operator*=(const Integer &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const Integer &k) { return Point(x * k, y * k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }
    constexpr Integer dot(const Point &r) const { return x * r.x + y * r.y; }
    constexpr Integer cross(const Point &r) const { return x * r.y - y * r.x; }
    constexpr Integer norm2() const { return x*x + y*y; }
    // 比較関数
    constexpr bool lex_comp(const Point &r) const {
        return sgn(x, r.x) < 0 || (sgn(x, r.x) == 0 and sgn(y, r.y) < 0);
    }
    constexpr bool arg_comp(const Point &r) const {
        int L = arg_type(x, y), R = arg_type(r.x, r.y);
        if (L != R) return L < R;
        Integer crs = (*this).cross(r);
        if (crs == 0) return abs(x) + abs(y) < abs(r.x) + abs(r.y);
        else return crs > 0;
    }
    // IO
    friend ostream &operator<<(ostream &os, Point &p) { return os << p.x << " " << p.y; }
    friend istream &operator>>(istream &is, Point &p) { is >> p.x >> p.y; return (is); }
};

Integer dot(Point a, Point b) { return a.dot(b); }
Integer cross(Point a, Point b) { return a.cross(b); }
int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1; // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1; // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2; // c,a,b 一直線上
    if (sgn(c.norm2() - b.norm2()) == 1) return -2; // a,b,c 一直線上
    return 0; // a,c,b 一直線上
}

vector<Point> convex_hull(vector<Point> ps, bool ONSEG = false) {
    int n = (int)ps.size();
    if (n <= 2) return ps;
    sort(ps.begin(), ps.end(), [&](auto i, auto j) {
        return i.lex_comp(j);
    });
    int k = 0; // 凸包の頂点数
    vector<Point> qs(2*n); // 構築中の凸包

    auto check = [&](int c) {
        return ONSEG ? c == -1 : c <= 0;
    };
    // Build lower hull
    for (int i = 0; i < n; ++i) {
        while (k >= 2 and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }
    // Build upper hull
    for (int i = n - 2, t = k + 1; i >= 0; --i) {
        while (k >= t and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }

    qs.resize(k-1);
    return qs;
}

// 原点と他2点を選んで三角形の面積を最大化(2倍の値で返す)
// AOJ 3264
Integer calc_maximum_triangle(vector<Point> ps) {
    ps = convex_hull(ps);
    int n = (int)ps.size();
    if (n <= 2) return 0;
    Integer res = 0;
    int r = 0;
    for (int l = 0; l < n; ++l) {
        Integer cur = cross(ps[l], ps[r]);
        while (true) {
            int k = (r+1 == n) ? 0 : r+1;
            Integer nxt = cross(ps[l], ps[k]);
            if (cur < nxt) cur = nxt, r = k;
            else break;
        }
        res = max(res, cur);
        if (l == r) r += 1;
    }
    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<Point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i];
    }

    // fix i && p[i] -> (0,0)
    // S = a_j * a_k * |x_j * y_k - x_k * y_j|
    for (int i = 0; i < n; ++i) {
        vector<Point> qs(n-1);
        for (int j = 0, k = 0; j < n; ++j) {
            if (i == j) continue;
            qs[k++] = (p[j]-p[i]) * a[j];
        }
        cout << calc_maximum_triangle(qs)*a[i] << "\n";
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3596
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

// 整数幾何
typedef ll Integer;
const Integer eps = 0;
inline constexpr int sgn(Integer a, Integer b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline constexpr int arg_type(Integer x, Integer y) { return y < 0 ? 2 : x < 0 ? 1 : 0; }
struct Point {
    Integer x, y;
    constexpr Point(Integer x = 0, Integer y = 0) : x(x), y(y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr Point &operator*=(const Integer &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const Integer &k) { return Point(x * k, y * k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }
    constexpr Integer dot(const Point &r) const { return x * r.x + y * r.y; }
    constexpr Integer cross(const Point &r) const { return x * r.y - y * r.x; }
    constexpr Integer norm2() const { return x*x + y*y; }
    // 比較関数
    constexpr bool lex_comp(const Point &r) const {
        return sgn(x, r.x) < 0 || (sgn(x, r.x) == 0 and sgn(y, r.y) < 0);
    }
    constexpr bool arg_comp(const Point &r) const {
        int L = arg_type(x, y), R = arg_type(r.x, r.y);
        if (L != R) return L < R;
        Integer crs = (*this).cross(r);
        if (crs == 0) return abs(x) + abs(y) < abs(r.x) + abs(r.y);
        else return crs > 0;
    }
    // IO
    friend ostream &operator<<(ostream &os, Point &p) { return os << p.x << " " << p.y; }
    friend istream &operator>>(istream &is, Point &p) { is >> p.x >> p.y; return (is); }
};

Integer dot(Point a, Point b) { return a.dot(b); }
Integer cross(Point a, Point b) { return a.cross(b); }
int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1; // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1; // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2; // c,a,b 一直線上
    if (sgn(c.norm2() - b.norm2()) == 1) return -2; // a,b,c 一直線上
    return 0; // a,c,b 一直線上
}

vector<Point> convex_hull(vector<Point> ps, bool ONSEG = false) {
    int n = (int)ps.size();
    if (n <= 2) return ps;
    sort(ps.begin(), ps.end(), [&](auto i, auto j) {
        return i.lex_comp(j);
    });
    int k = 0; // 凸包の頂点数
    vector<Point> qs(2*n); // 構築中の凸包

    auto check = [&](int c) {
        return ONSEG ? c == -1 : c <= 0;
    };
    // Build lower hull
    for (int i = 0; i < n; ++i) {
        while (k >= 2 and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }
    // Build upper hull
    for (int i = n - 2, t = k + 1; i >= 0; --i) {
        while (k >= t and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }

    qs.resize(k-1);
    return qs;
}

// 原点と他2点を選んで三角形の面積を最大化(2倍の値で返す)
// AOJ 3264
Integer calc_maximum_triangle(vector<Point> ps) {
    ps = convex_hull(ps);
    int n = (int)ps.size();
    if (n <= 2) return 0;
    for (int i = 0; i < n; ++i) {
        ps.push_back(ps[i]);
    }
    Integer res = 0;
    int r = 0;
    for (int l = 0; l < n; ++l) {
        while (cross(ps[l], ps[r]) < cross(ps[l], ps[r+1])) r += 1;
        res = max(res, cross(ps[l], ps[r]));
        if (l == r) r += 1;
    }
    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<Point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i];
    }

    // fix i && p[i] -> (0,0)
    // S = a_j * a_k * |x_j * y_k - x_k * y_j|
    for (int i = 0; i < n; ++i) {
        vector<Point> qs(n-1);
        for (int j = 0, k = 0; j < n; ++j) {
            if (i == j) continue;
            qs[k++] = (p[j]-p[i]) * a[j];
        }
        cout << calc_maximum_triangle(qs)*a[i] << "\n";
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3596
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

// 整数幾何
typedef ll Integer;
const Integer eps = 0;
inline constexpr int sgn(Integer a, Integer b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline constexpr int arg_type(Integer x, Integer y) { return y < 0 ? 2 : x < 0 ? 1 : 0; }
struct Point {
    Integer x, y;
    constexpr Point(Integer x = 0, Integer y = 0) : x(x), y(y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr Point &operator*=(const Integer &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const Integer &k) { return Point(x * k, y * k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }
    constexpr Integer dot(const Point &r) const { return x * r.x + y * r.y; }
    constexpr Integer cross(const Point &r) const { return x * r.y - y * r.x; }
    constexpr Integer norm2() const { return x*x + y*y; }
    // 比較関数
    constexpr bool lex_comp(const Point &r) const {
        return sgn(x, r.x) < 0 || (sgn(x, r.x) == 0 and sgn(y, r.y) < 0);
    }
    constexpr bool arg_comp(const Point &r) const {
        int L = arg_type(x, y), R = arg_type(r.x, r.y);
        if (L != R) return L < R;
        Integer crs = (*this).cross(r);
        if (crs == 0) return abs(x) + abs(y) < abs(r.x) + abs(r.y);
        else return crs > 0;
    }
    // IO
    friend ostream &operator<<(ostream &os, Point &p) { return os << p.x << " " << p.y; }
    friend istream &operator>>(istream &is, Point &p) { is >> p.x >> p.y; return (is); }
};

Integer dot(Point a, Point b) { return a.dot(b); }
Integer cross(Point a, Point b) { return a.cross(b); }
int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1; // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1; // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2; // c,a,b 一直線上
    if (sgn(c.norm2() - b.norm2()) == 1) return -2; // a,b,c 一直線上
    return 0; // a,c,b 一直線上
}

vector<Point> convex_hull(vector<Point> ps, bool ONSEG = false) {
    int n = (int)ps.size();
    if (n <= 2) return ps;
    sort(ps.begin(), ps.end(), [&](auto i, auto j) {
        return i.lex_comp(j);
    });
    int k = 0; // 凸包の頂点数
    vector<Point> qs(2*n); // 構築中の凸包

    auto check = [&](int c) {
        return ONSEG ? c == -1 : c <= 0;
    };
    // Build lower hull
    for (int i = 0; i < n; ++i) {
        while (k >= 2 and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }
    // Build upper hull
    for (int i = n - 2, t = k + 1; i >= 0; --i) {
        while (k >= t and check(ccw(qs[k-2], qs[k-1], ps[i]))) k--;
        qs[k++] = ps[i];
    }

    qs.resize(k-1);
    return qs;
}

// 原点と他2点を選んで三角形の面積を最大化(2倍の値で返す)
// AOJ 3264
Integer calc_maximum_triangle(vector<Point> ps) {
    ps = convex_hull(ps);
    int n = (int)ps.size();
    if (n <= 2) return 0;
    for (int i = 0; i < n; ++i) {
        ps.push_back(ps[i]);
    }
    Integer res = 0;
    int r = 0;
    for (int l = 0; l < n; ++l) {
        while (r < l || cross(ps[l], ps[r]) < cross(ps[l], ps[r+1])) r += 1;
        res = max(res, cross(ps[l], ps[r]));
    }
    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<Point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i];
    }

    // fix i && p[i] -> (0,0)
    // S = a_j * a_k * |x_j * y_k - x_k * y_j|
    for (int i = 0; i < n; ++i) {
        vector<Point> qs(n-1);
        for (int j = 0, k = 0; j < n; ++j) {
            if (i == j) continue;
            qs[k++] = (p[j]-p[i]) * a[j];
        }
        cout << calc_maximum_triangle(qs)*a[i] << "\n";
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3524
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int quadrant(long long x, long long y) {
	if (y == 0) return x > 0 ? 0 : 4;
	if (x == 0) return y > 0 ? 2 : 6;
	if (y > 0) return x > 0 ? 1 : 3;
	return x > 0 ? 7 : 5;
}

long long solve(int N, const vector<long long>& X, const vector<long long>& Y) {
	auto calc = [&](int v1, int v2) -> long long {
		return 1LL * X[v1] * Y[v2] - 1LL * X[v2] * Y[v1];
	};
	vector<int> perm(N);
	for (int i = 0; i < N; i++) {
		perm[i] = i;
	}
	sort(perm.begin(), perm.end(), [&](int va, int vb) {
		int qa = quadrant(X[va], Y[va]);
		int qb = quadrant(X[vb], Y[vb]);
		if (qa != qb) return qa < qb;
		return calc(va, vb) > 0;
	});
	long long best = -1;
	int pos = -1;
	for (int i = 0; i < N; i++) {
		int v1 = perm[i];
		int v2 = perm[(i + 1) % N];
		if (calc(v1, v2) < 0) {
			pos = (i + 1) % N;
			best = -1;
			break;
		}
		long long d = X[v1] * X[v1] + Y[v1] * Y[v1];
		if (best < d) {
			best = d;
			pos = i;
		}
	}
	vector<int> st;
	for (int i = 0; i <= (best != -1 ? N : N - 1); i++) {
		int id = perm[(pos + i) % N];
		while (st.size() >= 2) {
			int v1 = st.back();
			int v2 = st[st.size() - 2];
			if (calc(v2, v1) + calc(v1, id) > calc(v2, id)) {
				break;
			}
			st.pop_back();
		}
		st.push_back(id);
	}
	if (best != -1) {
		st.pop_back();
	}
	int cur = 0;
	long long ans = 0;
	for (int i = 0; i < st.size(); i++) {
		while ((best != -1 || cur + 1 != st.size()) && calc(st[i], st[cur % st.size()]) <= calc(st[i], st[(cur + 1) % st.size()])) {
			cur += 1;
		}
		ans = max(ans, calc(st[i], st[cur % st.size()]));
	}
	return ans;
}

int main() {
	int N;
	cin >> N;
	vector<long long> A(N), X(N), Y(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	for (int i = 0; i < N; i++) {
		cin >> X[i] >> Y[i];
	}
	for (int i = 0; i < N; i++) {
		vector<long long> px(N - 1), py(N - 1);
		for (int j = 0; j < N - 1; j++) {
			int id = (j < i ? j : j + 1);
			px[j] = (X[id] - X[i]) * A[id];
			py[j] = (Y[id] - Y[i]) * A[id];
		}
		long long ans = solve(N - 1, px, py);
		cout << ans * A[i] << '\n';
	}
	return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 3452
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

int quadrant(long long x, long long y) {
	if (y == 0) return x > 0 ? 0 : 4;
	if (x == 0) return y > 0 ? 2 : 6;
	if (y > 0) return x > 0 ? 1 : 3;
	return x > 0 ? 7 : 5;
}

long long solve(int N, const vector<long long>& X, const vector<long long>& Y) {
	auto calc = [&](int v1, int v2) -> long long {
		return 1LL * X[v1] * Y[v2] - 1LL * X[v2] * Y[v1];
	};
	vector<int> perm(N);
	for (int i = 0; i < N; i++) {
		perm[i] = i;
	}
	sort(perm.begin(), perm.end(), [&](int va, int vb) {
		int qa = quadrant(X[va], Y[va]);
		int qb = quadrant(X[vb], Y[vb]);
		if (qa != qb) return qa < qb;
		return calc(va, vb) > 0;
	});
	long long best = -1;
	int pos = -1;
	for (int i = 0; i < N; i++) {
		int v1 = perm[i];
		int v2 = perm[(i + 1) % N];
		if (calc(v1, v2) < 0) {
			pos = (i + 1) % N;
			best = -1;
			break;
		}
		long long d = X[v1] * X[v1] + Y[v1] * Y[v1];
		if (best < d) {
			best = d;
			pos = i;
		}
	}
	vector<int> st;
	for (int i = 0; i <= (best != -1 ? N : N - 1); i++) {
		int id = perm[(pos + i) % N];
		while (st.size() >= 2) {
			int v1 = st.back();
			int v2 = st[st.size() - 2];
			if (calc(v2, v1) + calc(v1, id) > calc(v2, id)) {
				break;
			}
			st.pop_back();
		}
		st.push_back(id);
	}
	if (best != -1) {
		st.pop_back();
	}
	int cur = 0;
	long long ans = 0;
	for (int i = 0; i < st.size(); i++) {
		while ((best != -1 || cur + 1 != st.size()) && calc(st[i], st[cur % st.size()]) < calc(st[i], st[(cur + 1) % st.size()])) {
			cur += 1;
		}
		ans = max(ans, calc(st[i], st[cur % st.size()]));
	}
	return ans;
}

int main() {
	int N;
	cin >> N;
	vector<long long> A(N), X(N), Y(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	for (int i = 0; i < N; i++) {
		cin >> X[i] >> Y[i];
	}
	for (int i = 0; i < N; i++) {
		vector<long long> px(N - 1), py(N - 1);
		for (int j = 0; j < N - 1; j++) {
			int id = (j < i ? j : j + 1);
			px[j] = (X[id] - X[i]) * A[id];
			py[j] = (Y[id] - Y[i]) * A[id];
		}
		long long ans = solve(N - 1, px, py);
		cout << ans * A[i] << '\n';
	}
	return 0;
}
accuracy: 0.8235294117647058
time_ms: 390
memory_kb: 3456
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

// =================================================== Point Class ===================================================
struct Point {
    long long px, py;
};

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

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

long long crs(Point a1, Point a2) {
    return a1.px * a2.py - a1.py * a2.px;
}

// =================================================== Fraction Class ===================================================
struct Fraction {
    long long px, py;
};

bool operator<(const Fraction &a1, const Fraction &a2) {
    int sign1 = 0;
    int sign2 = 0;
    if (a1.px > 0 && a1.py >= 0) sign1 = 0;
    else if (a1.px <= 0 && a1.py > 0) sign1 = 1;
    else if (a1.px < 0 && a1.py <= 0) sign1 = 2;
    else sign1 = 3;
    if (a2.px > 0 && a2.py >= 0) sign2 = 0;
    else if (a2.px <= 0 && a2.py > 0) sign2 = 1;
    else if (a2.px < 0 && a2.py <= 0) sign2 = 2;
    else sign2 = 3;
    if (sign1 < sign2) return true;
    if (sign1 > sign2) return false;
    if (a1.px * a2.py > a1.py * a2.px) return true;
    return false;
}

// =================================================== Main Function ===================================================
long long Solve(vector<Point> Vec) {
    sort(Vec.begin(), Vec.end());

    // Step 1. Get Convex Hull (Part 1)
    vector<Point> L1 = {Vec[0]};
    for (int i = 1; i < (int)Vec.size(); i++) {
        while (L1.size() >= 2) {
            Point V1 = L1[L1.size() - 2];
            Point V2 = L1[L1.size() - 1];
            if (crs(V2 - V1, Vec[i] - V2) <= 0) L1.pop_back();
            else break;
        }
        L1.push_back(Vec[i]);
    }

    // Step 2. Get Convex Hull (Part 2)
    vector<Point> L2 = {Vec[0]};
    for (int i = 1; i < (int)Vec.size(); i++) {
        while (L2.size() >= 2) {
            Point V1 = L2[L2.size() - 2];
            Point V2 = L2[L2.size() - 1];
            if (crs(V2 - V1, Vec[i] - V2) >= 0) L2.pop_back();
            else break;
        }
        L2.push_back(Vec[i]);
    }
    vector<Point> Convex = L1;
    for (int i = (int)L2.size() - 2; i >= 1; i--) Convex.push_back(L2[i]);

    // Step 3. Sort By Angle
    vector<Fraction> List;
    for (int i = 0; i < (int)Convex.size(); i++) {
        Point p1 = Convex[(i + 0) % Convex.size()];
        Point p2 = Convex[(i + 1) % Convex.size()];
        Point diff = p2 - p1;
        List.push_back(Fraction{diff.px, diff.py});
    }
    vector<Fraction> List2 = List;
    sort(List2.begin(), List2.end());
    
    // Debug Output
    /*cout << "Vec:" << endl;
    for (int i = 0; i < Vec.size(); i++) cout << "  - (" << Vec[i].px << "," << Vec[i].py << ")" << endl;
    cout << "Convex:" << endl;
    for (int i = 0; i < Convex.size(); i++) cout << "  - (" << Convex[i].px << "," << Convex[i].py << ")" << endl;
    cout << "Frac:" << endl;
    for (int i = 0; i < List.size(); i++) cout << "  - (" << List[i].px << "," << List[i].py << ")" << endl;
    cout << "Frac2:" << endl;
    for (int i = 0; i < List2.size(); i++) cout << "  - (" << List2[i].px << "," << List2[i].py << ")" << endl;*/

    // Step 4. Brute Force
    long long Answer = 0;
    for (int i = 0; i < Vec.size(); i++) {
        Fraction target1 = Fraction{ +Vec[i].px, +Vec[i].py };
        Fraction target2 = Fraction{ -Vec[i].px, -Vec[i].py };
        int pos1 = lower_bound(List.begin(), List.end(), target1) - List.begin();
        int pos2 = lower_bound(List.begin(), List.end(), target2) - List.begin();
        vector<int> Cand;
        for (int j = -1; j <= 1; j++) {
            Cand.push_back((pos1 + j + (int)Convex.size()) % Convex.size());
            Cand.push_back((pos2 + j + (int)Convex.size()) % Convex.size());
        }
        for (int j : Cand) {
            long long ret = abs(crs(Vec[i], Convex[j]));
            Answer = max(Answer, ret);
        }
    }

    // Step 5. Return
    return Answer;
}

// =================================================== Main Part ===================================================
long long N;
long long A[1 << 19];
Point G[1 << 19];

int main() {
    // Step 1. Input
    cin >> N;
    for (int i = 1; i <= N; i++) cin >> A[i];
    for (int i = 1; i <= N; i++) cin >> G[i].px >> G[i].py;

    // Step 2. Brute Force
    for (int i = 1; i <= N; i++) {
        vector<Point> List;
        for (int j = 1; j <= N; j++) {
            if (j == i) continue;
            Point diff = G[j] - G[i];
            List.push_back(Point{diff.px * A[j], diff.py * A[j]});
        }
        long long ret = Solve(List);
        cout << ret * A[i] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 5524
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

// f: [0, n) -> T
template < class T, class func > pair< int, T > find_local_minimum(func f, int n) {
    int a = 0, b = (n + 1) / 2, c = n + 1;
    while(c - a > 2) {
        int l = (a + b) / 2, r = (b + c + 1) / 2;
        if(f(l) < f(b))
            tie(a, b, c) = make_tuple(a, l, b);
        else if(f(b) > f(r))
            tie(a, b, c) = make_tuple(b, r, c);
        else
            tie(a, b, c) = make_tuple(l, b, r);
    }
    return {b, f(b)};
};

// f: [0, p) -> T, f(x) = f(x + p)
template < class T, class func > pair< int, T > find_minimum(func f, int p) {
    return find_local_minimum< T, func >(f, 2 * p - 1);
}

template < class T > vector< int > argsort(vector< T > &a) {
    vector< int > ids((int)a.size());
    iota(ids.begin(), ids.end(), 0);
    sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}

template < class T >
pair< vector< int >, vector< pair< T, T > > > convex_hull(vector< pair< T, T > > &points, string mode = "full", bool inclusive = false) {
    assert(mode == "full" || mode == "lower" || mode == "upper");
    int n = points.size();
    if(n == 1) return {{0}, {points[0]}};
    if(n == 2) return {{0, 1}, {points[0], points[1]}};
    vector<int> I = argsort(points);

    auto check = [&](int i, int j, int k) {
        auto [xi, yi] = points[i];
        auto [xj, yj] = points[j];
        auto [xk, yk] = points[k];
        T det = (xj - xi) * (yk - yj) - (yj - yi) * (xk - xj);
        return inclusive ? det >= 0 : det > 0;
    };

    auto calc = [&]() {
        vector<int> J;
        for(int k : I) {
            while(J.size() >= 2 && !check(J[J.size() - 2], J.back(), k)) {
                //if(check(J[J.size() - 2], J.back(), k)) break;
                J.pop_back();
            }
            J.push_back(k);
        }
        return J;
    };

    vector<int> ids;
    if(mode == "full" || mode == "lower") {
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "full" || mode == "upper") {
        if(!ids.empty()) ids.pop_back();
        reverse(I.begin(), I.end());
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "upper") reverse(ids.begin(), ids.end());
    if(ids.size() >= 2 && ids[0] == ids.back()) ids.pop_back();
    vector< pair< T, T > > ch;
    for(int i : ids) ch.push_back(points[i]);
    return {ids, ch};
}



template < class T > class CHT_xy {
  private:
    using Point = pair< T, T >;
    vector< Point > ps;
    bool is_prepared = false;

    T eval(int i, T x, T y) {
        i %= size(); if(i < 0) i += size();
        auto [a, b] = ps[i];
        return a * x + b * y;
    }

    struct rets {
        Point p; T v;
    };

  public:
    CHT_xy() {}
    CHT_xy(vector< Point > &ps) : ps(ps) {}

    int size() { return ps.size(); }

    void clear() { ps.clear(); is_prepared = false; }

    void add(Point p) {
        assert(!is_prepared);
        ps.push_back(p);
    }
    void add(T a, T b) {
        add(Point(a, b));
    }

    void build() {
        assert(!is_prepared);
        is_prepared = true;
        ps = convex_hull< T >(ps).second;
    }

    rets get_min(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return +eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], +minimum};
    }

    rets get_max(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return -eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], -minimum};
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];

    vector< pair<ll, ll> > p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    auto calc = [&](vector< pair< ll, ll > > &ps) -> ll {
        CHT_xy<ll> cht;
        for(auto [x, y] : ps) cht.add(-y, x);
        cht.build();
        ll ans = 0;
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_max(x, y).v));
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_min(x, y).v));
        return ans;
    };

    rep(i,n) {
        vector<pair<ll,ll>> ps;
        rep(j,n) if(j != i) {
            ll dx = p[j].first  - p[i].first;
            ll dy = p[j].second - p[i].second;
            dx *= a[j];
            dy *= a[j];
            ps.push_back({dx, dy});
        }

        cout << a[i] * calc(ps) << endl;
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 3644
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

// f: [0, n) -> T
template < class T, class func > pair< int, T > find_local_minimum(func f, int n) {
    int a = 0, b = (n + 1) / 2, c = n + 1;
    while(c - a > 2) {
        int l = (a + b) / 2, r = (b + c + 1) / 2;
        if(f(l) < f(b))
            tie(a, b, c) = make_tuple(a, l, b);
        else if(f(b) > f(r))
            tie(a, b, c) = make_tuple(b, r, c);
        else
            tie(a, b, c) = make_tuple(l, b, r);
    }
    return {b, f(b)};
};

// f: [0, p) -> T, f(x) = f(x + p)
template < class T, class func > pair< int, T > find_minimum(func f, int p) {
    return find_local_minimum< T, func >(f, 2 * p - 1);
}

template < class T > vector< int > argsort(vector< T > &a) {
    vector< int > ids((int)a.size());
    iota(ids.begin(), ids.end(), 0);
    sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}

template < class T >
pair< vector< int >, vector< pair< T, T > > > convex_hull(vector< pair< T, T > > &points, string mode = "full", bool inclusive = false) {
    assert(mode == "full" || mode == "lower" || mode == "upper");
    int n = points.size();
    if(n == 1) return {{0}, {points[0]}};
    if(n == 2) return {{0, 1}, {points[0], points[1]}};
    vector<int> I = argsort(points);

    auto check = [&](int i, int j, int k) {
        auto [xi, yi] = points[i];
        auto [xj, yj] = points[j];
        auto [xk, yk] = points[k];
        T det = (xj - xi) * (yk - yj) - (yj - yi) * (xk - xj);
        return inclusive ? det >= 0 : det > 0;
    };

    auto calc = [&]() {
        vector<int> J;
        for(int k : I) {
            while(J.size() >= 2) {
                if(check(J[J.size() - 2], J.back(), k)) break;
                J.pop_back();
            }
            J.push_back(k);
        }
        return J;
    };

    vector<int> ids;
    if(mode == "full" || mode == "lower") {
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "full" || mode == "upper") {
        if(!ids.empty()) ids.pop_back();
        reverse(I.begin(), I.end());
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "upper") reverse(ids.begin(), ids.end());
    if(ids.size() >= 2 && ids[0] == ids.back()) ids.pop_back();
    vector< pair< T, T > > ch;
    for(int i : ids) ch.push_back(points[i]);
    return {ids, ch};
}



template < class T > class CHT_xy {
  private:
    using Point = pair< T, T >;
    vector< Point > ps;
    bool is_prepared = false;

    T eval(int i, T x, T y) {
        i %= size(); if(i < 0) i += size();
        auto [a, b] = ps[i];
        return a * x + b * y;
    }

    struct rets {
        Point p; T v;
    };

  public:
    CHT_xy() {}
    CHT_xy(vector< Point > &ps) : ps(ps) {}

    int size() { return ps.size(); }

    void clear() { ps.clear(); is_prepared = false; }

    void add(Point p) {
        assert(!is_prepared);
        ps.push_back(p);
    }
    void add(T a, T b) {
        add(Point(a, b));
    }

    void build() {
        assert(!is_prepared);
        is_prepared = true;
        ps = convex_hull< T >(ps).second;
    }

    rets get_min(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return +eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], +minimum};
    }

    rets get_max(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return -eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], -minimum};
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];

    vector< pair<ll, ll> > p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    auto calc = [&](vector< pair< ll, ll > > &ps) -> ll {
        CHT_xy<ll> cht;
        for(auto [x, y] : ps) cht.add(-y, x);
        cht.build();
        ll ans = 0;
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_max(x, y).v));
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_min(x, y).v));
        return ans;
    };

    rep(i,n) {
        vector<pair<ll,ll>> ps;
        rep(j,n) if(j != i) {
            ll dx = p[j].first  - p[i].first;
            ll dy = p[j].second - p[i].second;
            dx *= a[j];
            dy *= a[j];
            ps.push_back({dx, dy});
        }

        cout << a[i] * calc(ps) << endl;
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 3608
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

// f: [0, n) -> T
template < class T, class func > pair< int, T > find_local_minimum(func f, int n) {
    int a = 0, b = (n + 1) / 2, c = n + 1;
    while(c - a > 2) {
        int l = (a + b) / 2, r = (b + c + 1) / 2;
        if(f(l) < f(b))
            tie(a, b, c) = make_tuple(a, l, b);
        else if(f(b) > f(r))
            tie(a, b, c) = make_tuple(b, r, c);
        else
            tie(a, b, c) = make_tuple(l, b, r);
    }
    return {b, f(b)};
};

// f: [0, p) -> T, f(x) = f(x + p)
template < class T, class func > pair< int, T > find_minimum(func f, int p) {
    return find_local_minimum< T, func >(f, 2 * p - 1);
}

template < class T > vector< int > argsort(vector< T > &a) {
    vector< int > ids((int)a.size());
    iota(ids.begin(), ids.end(), 0);
    sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}

template < class T >
pair< vector< int >, vector< pair< T, T > > > convex_hull(vector< pair< T, T > > &points, string mode = "full", bool inclusive = false) {
    assert(mode == "full" || mode == "lower" || mode == "upper");
    int n = points.size();
    if(n == 1) return {{0}, {points[0]}};
    if(n == 2) return {{0, 1}, {points[0], points[1]}};
    vector<int> I = argsort(points);

    auto check = [&](int i, int j, int k) {
        auto [xi, yi] = points[i];
        auto [xj, yj] = points[j];
        auto [xk, yk] = points[k];
        T det = (xj - xi) * (yk - yj) - (yj - yi) * (xk - xj);
        return inclusive ? det >= 0 : det > 0;
    };

    auto calc = [&]() {
        vector<int> J;
        for(int k : I) {
            while(J.size() >= 2) {
                if(check(J[J.size() - 2], J.back(), k)) break;
                J.pop_back();
            }
            J.push_back(k);
        }
        return J;
    };

    vector<int> ids;
    if(mode == "full" || mode == "lower") {
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "full" || mode == "upper") {
        if(!ids.empty()) ids.pop_back();
        reverse(I.begin(), I.end());
        vector<int> J = calc();
        ids.insert(ids.end(), J.begin(), J.end());
    }
    if(mode == "upper") reverse(ids.begin(), ids.end());
    if(ids.size() >= 2 && ids[0] == ids.back()) ids.pop_back();
    vector< pair< T, T > > ch;
    for(int i : ids) ch.push_back(points[i]);
    return {ids, ch};
}



template < class T > class CHT_xy {
  private:
    using Point = pair< T, T >;
    vector< Point > ps;
    bool is_prepared = false;

    T eval(int i, T x, T y) {
        i %= size(); if(i < 0) i += size();
        auto [a, b] = ps[i];
        return a * x + b * y;
    }

  public:
    CHT_xy() {}
    CHT_xy(vector< Point > &ps) : ps(ps) {}

    int size() { return ps.size(); }

    void clear() { ps.clear(); is_prepared = false; }

    void add(Point p) {
        assert(!is_prepared);
        ps.push_back(p);
    }
    void add(T a, T b) {
        add(Point(a, b));
    }

    void build() {
        assert(!is_prepared);
        is_prepared = true;
        ps = convex_hull< T >(ps).second;
    }

    pair< Point, T > get_min(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return +eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], +minimum};
    }

    pair< Point, T > get_max(T x, T y) {
        assert(is_prepared);
        auto f = [&](int i) -> T { return -eval(i, x, y); };
        auto [i, minimum] = find_minimum< T >(f, size());
        return {ps[i], -minimum};
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];

    vector< pair<ll, ll> > p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    auto calc = [&](vector< pair< ll, ll > > &ps) -> ll {
        CHT_xy<ll> cht;
        for(auto [x, y] : ps) cht.add(-y, x);
        cht.build();
        ll ans = 0;
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_max(x, y).second));
        for(auto [x, y] : ps) ans = max(ans, abs(cht.get_min(x, y).second));
        return ans;
    };

    rep(i,n) {
        vector<pair<ll,ll>> ps;
        rep(j,n) if(j != i) {
            ll dx = p[j].first  - p[i].first;
            ll dy = p[j].second - p[i].second;
            dx *= a[j];
            dy *= a[j];
            ps.push_back({dx, dy});
        }

        cout << a[i] * calc(ps) << endl;
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 3572
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

template < class T > class CHT_add_monotone {
    struct Line {
        T a, b;
        Line(T a, T b) : a(a), b(b) {}
        T eval(T x) { return a * x + b; }
    };

    deque< Line > H;
    T sgn;

    int sgn_of(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }

    using D = long double;
    bool check(Line &a, Line &b, Line &c) {
        if(a.b == b.b || b.b == c.b) return sgn_of(b.a - a.a) * sgn_of(c.b - b.b) >= sgn_of(c.a - b.a) * sgn_of(b.b - a.b);
        return D(b.a - a.a) * sgn_of(c.b - b.b) / D(abs(b.b - a.b)) >= D(c.a - b.a) * sgn_of(b.b - a.b) / D(abs(c.b - b.b));
    }

  public:

    CHT_add_monotone(bool is_min = true) { sgn = is_min ? +1 : -1; }

    bool empty() { return H.empty(); }

    void clear() { H.clear(); }

    void add(T a, T b) {
        a *= sgn, b *= sgn;
        Line l(a, b);
        if(empty()) {
            H.push_front(l);
        } else if(H.front().a <= a) {
            if(H.front().a == a) {
                if(H.front().b <= b) return;
                H.pop_front();
            }
            while(H.size() >= 2 && check(l, H.front(), H[1])) H.pop_front();
            H.push_front(l);
        } else {
            assert(a <= H.back().a);
            if(H.back().a == a) {
                if(H.back().b <= b) return;
                H.pop_back();
            }
            while(H.size() >= 2 && check(H[H.size() - 2], H.back(), l)) H.pop_back();
            H.push_back(l);
        }
    }

    T query(T x) {
        assert(!empty());
        int l = -1, r = H.size() - 1;
        while(l + 1 < r) {
            int m = (l + r) / 2;
            (H[m].eval(x) >= H[m + 1].eval(x) ? l : r) = m;
        }
        return sgn * H[r].eval(x);
    }

    T query_monotone_inc(T x) {
        assert(!empty());
        while(H.size() >= 2 && H.front().eval(x) >= H[1].eval(x)) H.pop_front();
        return sgn * H.front().eval(x);
    }

    T query_monotone_dec(T x) {
        assert(!empty());
        while(H.size() >= 2 && H.back().eval(x) >= H[H.size() - 2].eval(x)) H.pop_back();
        return sgn * H.back().eval(x);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];
    vector<pair<ll,ll>> p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    rep(i,n) {
        ll ans = 0;
        vector<pair<ll,ll>> v;
        rep(j,n) if(j != i) {
            auto [xi, yi] = p[i];
            auto [xj, yj] = p[j];
            v.push_back({a[j] * (xj - xi), a[j] * (yj - yi)});
        }

        CHT_add_monotone<long double> cht_min(true), cht_max(false);
        sort(v.begin(), v.end(), [&](auto L, auto R){ return L.first < R.first; });
        for(auto [x, y] : v) cht_min.add(x, y), cht_max.add(x, y);
        for(auto [x, y] : v) {
            ll cur = -1;
            if(x >= 0) {
                cur = llround(cht_max.query((long double)-1.0 * y / x) * x);
            } else {
                cur = llround(cht_min.query((long double)-1.0 * y / x) * x);
            }
            ans = max(ans, cur * a[i]);
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 480
memory_kb: 3524
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

template < class T > class CHT_add_monotone {
    struct Line {
        T a, b;
        Line(T a, T b) : a(a), b(b) {}
        T eval(T x) { return a * x + b; }
    };

    deque< Line > H;
    T sgn;

    int sgn_of(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }

    using D = long double;
    bool check(Line &a, Line &b, Line &c) {
        if(a.b == b.b || b.b == c.b) return sgn_of(b.a - a.a) * sgn_of(c.b - b.b) >= sgn_of(c.a - b.a) * sgn_of(b.b - a.b);
        return D(b.a - a.a) * sgn_of(c.b - b.b) / D(abs(b.b - a.b)) >= D(c.a - b.a) * sgn_of(b.b - a.b) / D(abs(c.b - b.b));
    }

  public:

    CHT_add_monotone(bool is_min = true) { sgn = is_min ? +1 : -1; }

    bool empty() { return H.empty(); }

    void clear() { H.clear(); }

    void add(T a, T b) {
        a *= sgn, b *= sgn;
        Line l(a, b);
        if(empty()) {
            H.push_front(l);
        } else if(H.front().a <= a) {
            if(H.front().a == a) {
                if(H.front().b <= b) return;
                H.pop_front();
            }
            while(H.size() >= 2 && check(l, H.front(), H[1])) H.pop_front();
            H.push_front(l);
        } else {
            assert(a <= H.back().a);
            if(H.back().a == a) {
                if(H.back().b <= b) return;
                H.pop_back();
            }
            while(H.size() >= 2 && check(H[H.size() - 2], H.back(), l)) H.pop_back();
            H.push_back(l);
        }
    }

    T query(T x) {
        assert(!empty());
        int l = -1, r = H.size() - 1;
        while(l + 1 < r) {
            int m = (l + r) / 2;
            (H[m].eval(x) >= H[m + 1].eval(x) ? l : r) = m;
        }
        return sgn * H[r].eval(x);
    }

    T query_monotone_inc(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return sgn * H.front().eval(x);
    }

    T query_monotone_dec(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return sgn * H.front().eval(x);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];
    vector<pair<ll,ll>> p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    rep(i,n) {
        ll ans = 0;
        vector<pair<ll,ll>> v;
        rep(j,n) if(j != i) {
            auto [xi, yi] = p[i];
            auto [xj, yj] = p[j];
            v.push_back({a[j] * (xj - xi), a[j] * (yj - yi)});
        }

        CHT_add_monotone<long double> cht_min(true), cht_max(false);
        sort(v.begin(), v.end(), [&](auto L, auto R){ return L.first < R.first; });
        for(auto [x, y] : v) cht_min.add(x, y), cht_max.add(x, y);
        for(auto [x, y] : v) {
            ll cur = -1;
            if(x >= 0) {
                cur = llround(cht_max.query((long double)-1.0 * y / x) * x);
            } else {
                cur = llround(cht_min.query((long double)-1.0 * y / x) * x);
            }
            ans = max(ans, cur * a[i]);
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 480
memory_kb: 3620
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

template < class T, bool is_min > class CHT_add_monotone {
  public:
    using P = pair<T, T>;
    deque<P> H;

    CHT_add_monotone() {}

    bool empty() { return H.empty(); }

    void clear() { H.clear(); }

    int sgn(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }

    using D = long double;
    bool check(P &a, P &b, P &c) {
        if(a.second == b.second || b.second == c.second) return sgn(b.first - a.first) * sgn(c.second - b.second) >= sgn(c.first - b.first) * sgn(b.second - a.second);
        return D(b.first - a.first) * sgn(c.second - b.second) / D(abs(b.second - a.second)) >= D(c.first - b.first) * sgn(b.second - a.second) / D(abs(c.second - b.second));
    }

    void add(T a, T b) {
        if(!is_min) a *= -1, b *= -1;
        P line(a, b);
        if(empty()) {
            H.push_front(line);
            return;
        }

        if(H.front().first <= a) {
            if(H.front().first == a) {
                if(H.front().second <= b) return;
                H.pop_front();
            }
            while(H.size() >= 2 && check(line, H.front(), H[1])) H.pop_front();
            H.push_front(line);
        } else {
            assert(a <= H.back().first);
            if(H.back().first == a) {
                if(H.back().second <= b) return;
                H.pop_back();
            }
            while(H.size() >= 2 && check(H[H.size() - 2], H.back(), line)) H.pop_back();
            H.push_back(line);
        }
    }

    T get_y(P &a, T &x){ return a.first * x + a.second; }

    T query(T x) {
        assert(!empty());
        int l = -1, r = H.size() - 1;
        while(l + 1 < r) {
            int m = (l + r) / 2;
            if(get_y(H[m], x) >= get_y(H[m + 1], x)) l = m;
            else r = m;
        }
        return (is_min ? +1 : -1) * get_y(H[r], x);
    }

    T query_monotone_inc(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return (is_min ? +1 : -1) * get_y(H.front(), x);
    }

    T query_monotone_dec(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return (is_min ? +1 : -1) * get_y(H.front(), x);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];
    vector<pair<ll,ll>> p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    rep(i,n) {
        ll ans = 0;
        vector<pair<ll,ll>> v;
        rep(j,n) if(j != i) {
            auto [xi, yi] = p[i];
            auto [xj, yj] = p[j];
            v.push_back({a[j] * (xj - xi), a[j] * (yj - yi)});
        }

        CHT_add_monotone<long double, true> cht_min;
        CHT_add_monotone<long double, false> cht_max;
        sort(v.begin(), v.end(), [&](auto L, auto R){ return L.first < R.first; });
        for(auto [x, y] : v) cht_min.add(x, y), cht_max.add(x, y);
        for(auto [x, y] : v) {
            ll cur = -1;
            if(x >= 0) {
                cur = llround(cht_max.query((long double)-1.0 * y / x) * x);
            } else {
                cur = llround(cht_min.query((long double)-1.0 * y / x) * x);
            }
            ans = max(ans, cur * a[i]);
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 460
memory_kb: 3516
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

template < class T, bool is_min > class CHT_add_monotone {
  public:
    using P = pair<T, T>;
    deque<P> H;

    CHT_add_monotone() {}

    bool empty() { return H.empty(); }

    void clear() { H.clear(); }

    int sgn(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }

    using D = long double;
    bool check(P &a, P &b, P &c) {
        if(a.second == b.second || b.second == c.second) return sgn(b.first - a.first) * sgn(c.second - b.second) >= sgn(c.first - b.first) * sgn(b.second - a.second);
        return D(b.first - a.first) * sgn(c.second - b.second) / D(abs(b.second - a.second)) >= D(c.first - b.first) * sgn(b.second - a.second) / D(abs(c.second - b.second));
    }

    void add(T a, T b) {
        if(is_min) a *= -1, b *= -1;
        P line(a, b);
        if(empty()) {
            H.push_front(line);
            return;
        }

        if(H.front().first <= a) {
            if(H.front().first == a) {
                if(H.front().second <= b) return;
                H.pop_front();
            }
            while(H.size() >= 2 && check(line, H.front(), H[1])) H.pop_front();
            H.push_front(line);
        } else {
            assert(a <= H.back().first);
            if(H.back().first == a) {
                if(H.back().second <= b) return;
                H.pop_back();
            }
            while(H.size() >= 2 && check(H[H.size() - 2], H.back(), line)) H.pop_back();
            H.push_back(line);
        }
    }

    T get_y(P &a, T &x){ return a.first * x + a.second; }

    T query(T x) {
        assert(!empty());
        int l = -1, r = H.size() - 1;
        while(l + 1 < r) {
            int m = (l + r) / 2;
            if(get_y(H[m], x) >= get_y(H[m + 1], x)) l = m;
            else r = m;
        }
        return (is_min ? +1 : -1) * get_y(H[r], x);
    }

    T query_monotone_inc(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return (is_min ? +1 : -1) * get_y(H.front(), x);
    }

    T query_monotone_dec(T x) {
        assert(!empty());
        while(H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x)) H.pop_front();
        return (is_min ? +1 : -1) * get_y(H.front(), x);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n; cin >> n;
    vector<ll> a(n);
    rep(i,n) cin >> a[i];
    vector<pair<ll,ll>> p(n);
    for(auto &[x, y] : p) cin >> x >> y;

    rep(i,n) {
        ll ans = 0;
        vector<pair<ll,ll>> v;
        rep(j,n) if(j != i) {
            auto [xi, yi] = p[i];
            auto [xj, yj] = p[j];
            v.push_back({a[j] * (xj - xi), a[j] * (yj - yi)});
        }

        CHT_add_monotone<long double, true> cht_min;
        CHT_add_monotone<long double, false> cht_max;
        sort(v.begin(), v.end(), [&](auto L, auto R){ return L.first < R.first; });
        for(auto [x, y] : v) cht_min.add(x, y), cht_max.add(x, y);
        for(auto [x, y] : v) {
            ll cur = -1;
            if(x >= 0) {
                cur = llround(cht_max.query((long double)-1.0 * y / x) * x);
            } else {
                cur = llround(cht_min.query((long double)-1.0 * y / x) * x);
            }
            ans = max(ans, cur * a[i]);
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 480
memory_kb: 3568
final_rank: 12

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<(n);i++)
#define ALL(v) v.begin(),v.end()

#define equals(a,b) (fabs((a)-(b))<EPS)

namespace geometry {
  const double EPS = 1e-10;
  const double PI = asinl(1) * 2;

  struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    Point operator+(Point p) {return Point(x+p.x,y+p.y);}
    Point operator-(Point p) {return Point(x-p.x,y-p.y);}
    Point operator*(double k){return Point(x*k,y*k);}
    Point operator/(double k){return Point(x/k,y/k);}
    double norm(){return x*x+y*y;}
    double abs(){return sqrt(norm());}

    bool operator<(const Point &p) const{
      return x!=p.x?x<p.x:y<p.y;
      //grid-point only
      //return !equals(x,p.x)?x<p.x:!equals(y,p.y)?y<p.y:0;
    }

    bool operator==(const Point &p) const{
      return fabs(x-p.x)<EPS and fabs(y-p.y)<EPS;
    }
  };

  bool sort_x(Point a,Point b){
    return a.x!=b.x?a.x<b.x:a.y<b.y;
  }

  bool sort_y(Point a,Point b){
    return a.y!=b.y?a.y<b.y:a.x<b.x;
  }

  typedef Point Vector;
  typedef vector<Point> Polygon;

  struct Segment{
    Point p1,p2;
    Segment(){}
    Segment(Point p1, Point p2):p1(p1),p2(p2){}
  };
  typedef Segment Line;

  struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point c,double r):c(c),r(r){}
  };

  double norm(Vector a){
    return a.x*a.x+a.y*a.y;
  }

  double abs(Vector a){
    return sqrt(norm(a));
  }

  double dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y;
  }

  double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
  }

  Point orth(Point p){return Point(-p.y,p.x);}

  bool isOrthogonal(Vector a,Vector b){
    return equals(dot(a,b),0.0);
  }

  bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
    return isOrthogonal(a1-a2,b1-b2);
  }

  bool isOrthogonal(Segment s1,Segment s2){
    return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
  }

  bool isParallel(Vector a,Vector b){
    return equals(cross(a,b),0.0);
  }

  bool isParallel(Point a1,Point a2,Point b1,Point b2){
    return isParallel(a1-a2,b1-b2);
  }

  bool isParallel(Segment s1,Segment s2){
    return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
  }

  Point project(Segment s,Point p){
    Vector base=s.p2-s.p1;
    double r=dot(p-s.p1,base)/norm(base);
    return s.p1+base*r;
  }

  Point reflect(Segment s,Point p){
    return p+(project(s,p)-p)*2.0;
  }

  double arg(Vector p){
    return atan2(p.y,p.x);
  }

  Vector polar(double a,double r){
    return Point(cos(r)*a,sin(r)*a);
  }

  // COUNTER CLOCKWISE
  static const int CCW_COUNTER_CLOCKWISE = 1;
  static const int CCW_CLOCKWISE = -1;
  static const int CCW_ONLINE_BACK = 2;
  static const int CCW_ONLINE_FRONT = -2;
  static const int CCW_ON_SEGMENT = 0;

  int ccw(Point p0,Point p1,Point p2){
    Vector a = p1-p0;
    Vector b = p2-p0;
    if(cross(a,b) > EPS) return CCW_COUNTER_CLOCKWISE;
    if(cross(a,b) < -EPS) return CCW_CLOCKWISE;
    if(dot(a,b) < -EPS) return CCW_ONLINE_BACK;
    if(a.norm()<b.norm()) return CCW_ONLINE_FRONT;
    return CCW_ON_SEGMENT;
  }

  bool intersectSS(Point p1,Point p2,Point p3,Point p4){
    return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 and
            ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
  }

  bool intersectSS(Segment s1,Segment s2){
    return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
  }

  bool intersectPS(Polygon p,Segment l){
    int n=p.size();
    for(int i=0;i<n;i++)
      if(intersectSS(Segment(p[i],p[(i+1)%n]),l)) return 1;
    return 0;
  }

  double getDistanceLP(Line l,Point p){
    return fabs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
  }

  double getDistanceSP(Segment s,Point p){
    if(dot(s.p2-s.p1,p-s.p1) < 0.0 ) return abs(p-s.p1);
    if(dot(s.p1-s.p2,p-s.p2) < 0.0 ) return abs(p-s.p2);
    return getDistanceLP(s,p);
  }

  double getDistanceSS(Segment s1,Segment s2){
    if(intersectSS(s1,s2)) return 0.0;
    return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
               min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
  }

  // intercsect of circles
  static const int ICC_SEPERATE = 4;
  static const int ICC_CIRCUMSCRIBE = 3;
  static const int ICC_INTERSECT = 2;
  static const int ICC_INSCRIBE = 1;
  static const int ICC_CONTAIN = 0;

  int intersectCC(Circle c1,Circle c2){
    if(c1.r<c2.r) swap(c1,c2);
    double d=abs(c1.c-c2.c);
    double r=c1.r+c2.r;
    if(equals(d,r)) return ICC_CIRCUMSCRIBE;
    if(d>r) return ICC_SEPERATE;
    if(equals(d+c2.r,c1.r)) return ICC_INSCRIBE;
    if(d+c2.r<c1.r) return ICC_CONTAIN;
    return ICC_INTERSECT;
  }

  bool intersectSC(Segment s,Circle c){
    return getDistanceSP(s,c.c)<=c.r;
  }

  int intersectCS(Circle c,Segment s){
    if(norm(project(s,c.c)-c.c)-c.r*c.r>EPS) return 0;
    double d1=abs(c.c-s.p1),d2=abs(c.c-s.p2);
    if(d1<c.r+EPS and d2<c.r+EPS) return 0;
    if((d1<c.r-EPS and d2>c.r+EPS) or (d1>c.r+EPS and d2<c.r-EPS)) return 1;
    Point h=project(s,c.c);
    if(dot(s.p1-h,s.p2-h)<0) return 2;
    return 0;
  }

  Point getCrossPointSS(Segment s1,Segment s2){
    for(int k=0;k<2;k++){
      if(getDistanceSP(s1,s2.p1)<EPS) return s2.p1;
      if(getDistanceSP(s1,s2.p2)<EPS) return s2.p2;
      swap(s1,s2);
    }
    Vector base=s2.p2-s2.p1;
    double d1=fabs(cross(base,s1.p1-s2.p1));
    double d2=fabs(cross(base,s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
  }

  Point getCrossPointLL(Line l1,Line l2){
    double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
    double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
    if(fabs(a)<EPS and fabs(b)<EPS) return l2.p1;
    return l2.p1+(l2.p2-l2.p1)*(b/a);
  }

  Polygon getCrossPointCL(Circle c,Line l){
    Polygon ps;
    Point pr=project(l,c.c);
    Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
    if(equals(getDistanceLP(l,c.c),c.r)){
      ps.emplace_back(pr);
      return ps;
    }
    double base=sqrt(c.r*c.r-norm(pr-c.c));
    ps.emplace_back(pr+e*base);
    ps.emplace_back(pr-e*base);
    return ps;
  }

  Polygon getCrossPointCS(Circle c,Segment s){
    Line l(s);
    Polygon res=getCrossPointCL(c,l);
    if(intersectCS(c,s)==2) return res;
    if(res.size()>1u){
      if(dot(l.p1-res[0],l.p2-res[0])>0) swap(res[0],res[1]);
      res.pop_back();
    }
    return res;
  }


  Polygon getCrossPointCC(Circle c1,Circle c2){
    Polygon p(2);
    double d=abs(c1.c-c2.c);
    double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t=arg(c2.c-c1.c);
    p[0]=c1.c+polar(c1.r,t+a);
    p[1]=c1.c+polar(c1.r,t-a);
    return p;
  }

  // IN:2 ON:1 OUT:0
  int contains(Polygon g,Point p){
    int n=g.size();
    bool x=false;
    for(int i=0;i<n;i++){
      Point a=g[i]-p,b=g[(i+1)%n]-p;
      if(fabs(cross(a,b)) < EPS and dot(a,b) < EPS) return 1;
      if(a.y>b.y) swap(a,b);
      if(a.y < EPS and EPS < b.y and cross(a,b) > EPS ) x = !x;
    }
    return (x?2:0);
  }

  Polygon andrewScan(Polygon s){
    Polygon u,l;
    if(s.size()<3) return s;
    sort(s.begin(),s.end());
    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);
    for(int i=2;i<(int)s.size();i++){
      for(int n=u.size();
          n>=2 and ccw(u[n-2],u[n-1],s[i])!=CCW_CLOCKWISE;
          n--){
        u.pop_back();
      }
      u.push_back(s[i]);
    }
    for(int i=s.size()-3;i>=0;i--){
      for(int n=l.size();
          n>=2 and ccw(l[n-2],l[n-1],s[i])!=CCW_CLOCKWISE;
          n--){
        l.pop_back();
      }
      l.push_back(s[i]);
    }
    reverse(l.begin(),l.end());
    for(int i=u.size()-2;i>=1;i--) l.push_back(u[i]);
    return l;
  }

  Polygon convex_hull(Polygon ps){
    int n=ps.size();
    sort(ps.begin(),ps.end(),sort_y);
    int k=0;
    Polygon qs(n*2);
    for(int i=0;i<n;i++){
      while(k>1 and cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<=0) k--;
      qs[k++]=ps[i];
    }
    for(int i=n-2,t=k;i>=0;i--){
      while(k>t and cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<=0) k--;
      qs[k++]=ps[i];
    }
    qs.resize(k-1);
    return qs;
  }

  double diameter(Polygon s){
    Polygon p=s;
    int n=p.size();
    if(n==2) return abs(p[0]-p[1]);
    int i=0,j=0;
    for(int k=0;k<n;k++){
      if(p[i]<p[k]) i=k;
      if(!(p[j]<p[k])) j=k;
    }
    double res=0;
    int si=i,sj=j;
    while(i!=sj or j!=si){
      res=max(res,abs(p[i]-p[j]));
      if(cross(p[(i+1)%n]-p[i],p[(j+1)%n]-p[j])<0.0){
        i=(i+1)%n;
      }else{
        j=(j+1)%n;
      }
    }
    return res;
  }

  bool isConvex(Polygon p){
    bool f=1;
    int n=p.size();
    for(int i=0;i<n;i++){
      int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
      f&=t!=CCW_CLOCKWISE;
    }
    return f;
  }

  double area(Polygon s){
    double res=0;
    for(int i=0;i<(int)s.size();i++){
      res+=cross(s[i],s[(i+1)%s.size()])/2.0;
    }
    return res;
  }

  double area(Circle c1,Circle c2){
    double d=abs(c1.c-c2.c);
    if(c1.r+c2.r<=d+EPS) return 0;
    if(d<=fabs(c1.r-c2.r)){
      double r=min(c1.r,c2.r);
      return PI*r*r;
    }
    double res=0;
    for(int k=0;k<2;k++){
      double rc=(d*d+c1.r*c1.r-c2.r*c2.r)/(2*d*c1.r);
      double th=acosl(rc)*2;
      res+=(th-sinl(th))*c1.r*c1.r/2;
      swap(c1,c2);
    }
    return res;
  }

  Polygon convexCut(Polygon p,Line l){
    Polygon q;
    for(int i=0;i<(int)p.size();i++){
      Point a=p[i],b=p[(i+1)%p.size()];
      if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
      if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
        q.push_back(getCrossPointLL(Line(a,b),l));
    }
    return q;
  }

  Line bisector(Point p1,Point p2){
    Circle c1=Circle(p1,abs(p1-p2)),c2=Circle(p2,abs(p1-p2));
    Polygon p=getCrossPointCC(c1,c2);
    if(cross(p2-p1,p[0]-p1)>0) swap(p[0],p[1]);
    return Line(p[0],p[1]);
  }

  Vector translate(Vector v,double theta){
    Vector res;
    res.x=cos(theta)*v.x-sin(theta)*v.y;
    res.y=sin(theta)*v.x+cos(theta)*v.y;
    return res;
  }

  vector<Line> corner(Line l1,Line l2){
    vector<Line> res;
    if(isParallel(l1,l2)){
      double d=getDistanceLP(l1,l2.p1)/2.0;
      Vector v1=l1.p2-l1.p1;
      v1=v1/v1.abs()*d;
      Point p=l2.p1+translate(v1,90.0*(PI/180.0));
      double d1=getDistanceLP(l1,p);
      double d2=getDistanceLP(l2,p);
      if(fabs(d1-d2)>d){
        p=l2.p1+translate(v1,-90.0*(PI/180.0));
      }
      res.push_back(Line(p,p+v1));
    }else{
      Point p=getCrossPointLL(l1,l2);
      Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
      v1=v1/v1.abs();
      v2=v2/v2.abs();
      res.push_back(Line(p,p+(v1+v2)));
      res.push_back(Line(p,p+translate(v1+v2,90.0*(PI/180.0))));
    }
    return res;
  }

  Polygon tangent(Circle c1,Point p2){
    Circle c2=Circle(p2,sqrt(norm(c1.c-p2)-c1.r*c1.r));
    Polygon p=getCrossPointCC(c1,c2);
    sort(p.begin(),p.end());
    return p;
  }

  vector<Line> tangent(Circle c1,Circle c2){
    vector<Line> ls;
    if(c1.r<c2.r) swap(c1,c2);
    double g=norm(c1.c-c2.c);
    if(equals(g,0)) return ls;
    Point u=(c2.c-c1.c)/sqrt(g);
    Point v=orth(u);
    for(int s=1;s>=-1;s-=2){
      double h=(c1.r+s*c2.r)/sqrt(g);
      if(equals(1-h*h,0)){
        ls.emplace_back(c1.c+u*c1.r,c1.c+(u+v)*c1.r);
      }else if(1-h*h>0){
        Point uu=u*h,vv=v*sqrt(1-h*h);
        ls.emplace_back(c1.c+(uu+vv)*c1.r,c2.c-(uu+vv)*c2.r*s);
        ls.emplace_back(c1.c+(uu-vv)*c1.r,c2.c-(uu-vv)*c2.r*s);
      }
    }

    return ls;
  }

  double closest_pair(Polygon &a,int l=0,int r=-1){
    if(r<0){
      r=a.size();
      sort(a.begin(),a.end(),sort_x);
    }
    if(r-l<=1) return abs(a[0]-a[1]);
    int m=(l+r)>>1;
    double x=a[m].x;
    double d=min(closest_pair(a,l,m),closest_pair(a,m,r));
    inplace_merge(a.begin()+l,a.begin()+m,a.begin()+r,sort_y);

    Polygon b;
    for(int i=l;i<r;i++){
      if(fabs(a[i].x-x)>=d) continue;
      for(int j=0;j<(int)b.size();j++){
        double dy=a[i].y-next(b.rbegin(),j)->y;
        if(dy>=d) break;
        d=min(d,abs(a[i]-*next(b.rbegin(),j)));
      }
      b.emplace_back(a[i]);
    }
    return d;
  }

  vector<vector<int>>
  segmentArrangement(vector<Segment> &ss, Polygon &ps){
    int n=ss.size();
    for(int i=0;i<n;i++){
      ps.emplace_back(ss[i].p1);
      ps.emplace_back(ss[i].p2);
      for(int j=i+1;j<n;j++)
        if(intersectSS(ss[i],ss[j]))
          ps.emplace_back(getCrossPointSS(ss[i],ss[j]));
    }
    sort(ps.begin(),ps.end());
    ps.erase(unique(ps.begin(),ps.end()),ps.end());

    vector<vector<int> > G(ps.size());
    for(int i=0;i<n;i++){
      vector<pair<double,int> > ls;
      for(int j=0;j<(int)ps.size();j++)
        if(getDistanceSP(ss[i],ps[j])<EPS)
          ls.emplace_back(make_pair(norm(ss[i].p1-ps[j]),j));

      sort(ls.begin(),ls.end());
      for(int j=0;j+1<(int)ls.size();j++){
        int a=ls[j].second,b=ls[j+1].second;
        G[a].emplace_back(b);
        G[b].emplace_back(a);
      }
    }
    for(auto &v:G){
      sort(v.begin(),v.end());
      v.erase(unique(v.begin(),v.end()),v.end());
    }
    return G;
  }

  struct EndPoint{
    Point p;
    int seg,st;
    EndPoint(){}
    EndPoint(Point p,int seg,int st):p(p),seg(seg),st(st){}
    bool operator<(const EndPoint &ep)const{
      if(p.y==ep.p.y) return st<ep.st;
      return p.y<ep.p.y;
    }
  };

  int manhattan_intersection(vector<Segment> ss,const int INF){
    const int BTM = 0;
    const int LFT = 1;
    const int RGH = 2;
    const int TOP = 3;

    int n=ss.size();
    vector<EndPoint> ep;
    for(int i=0;i<n;i++){
      if(ss[i].p1.y==ss[i].p2.y){
        if(ss[i].p1.x>ss[i].p2.x) swap(ss[i].p1,ss[i].p2);
        ep.emplace_back(ss[i].p1,i,LFT);
        ep.emplace_back(ss[i].p2,i,RGH);
      }else{
        if(ss[i].p1.y>ss[i].p2.y) swap(ss[i].p1,ss[i].p2);
        ep.emplace_back(ss[i].p1,i,BTM);
        ep.emplace_back(ss[i].p2,i,TOP);
      }
    }
    sort(ep.begin(),ep.end());

    set<int> bt;
    bt.insert(INF);

    int cnt=0;
    for(int i=0;i<n*2;i++){
      if(ep[i].st==TOP){
        bt.erase(ep[i].p.x);
      }else if(ep[i].st==BTM){
        bt.emplace(ep[i].p.x);
      }else if(ep[i].st==LFT){
        auto b=bt.lower_bound(ss[ep[i].seg].p1.x);
        auto e=bt.upper_bound(ss[ep[i].seg].p2.x);
        cnt+=distance(b,e);
      }
    }

    return cnt;
  }

  double area(Polygon ps,Circle c){
    if(ps.size()<3u) return 0;
    function<double(Circle, Point, Point)> dfs=
      [&](Circle c,Point a,Point b){
        Vector va=c.c-a,vb=c.c-b;
        double f=cross(va,vb),res=0;
        if(equals(f,0.0)) return res;
        if(max(abs(va),abs(vb))<c.r+EPS) return f;
        Vector d(dot(va,vb),cross(va,vb));
        if(getDistanceSP(Segment(a,b),c.c)>c.r-EPS)
          return c.r*c.r*atan2(d.y,d.x);
        auto u=getCrossPointCS(c,Segment(a,b));
        if(u.empty()) return res;
        if(u.size()>1u and dot(u[1]-u[0],a-u[0])>0) swap(u[0],u[1]);
        u.emplace(u.begin(),a);
        u.emplace_back(b);
        for(int i=1;i<(int)u.size();i++)
          res+=dfs(c,u[i-1],u[i]);
        return res;
      };
    double res=0;
    for(int i=0;i<(int)ps.size();i++)
      res+=dfs(c,ps[i],ps[(i+1)%ps.size()]);
    return res/2;
  }
}
using namespace geometry;

namespace geometry{
  istream &operator>>(istream &is,Point &p){
    is>>p.x>>p.y;
    return is;
  }
  istream &operator>>(istream &is,Polygon &p){
    for(int i=0;i<(int)p.size();i++) is>>p[i];
    return is;
  }
  istream &operator>>(istream &is,Segment &s){
    is>>s.p1>>s.p2;
    return is;
  }
  istream &operator>>(istream &is,Circle &c){
    is>>c.c>>c.r;
    return is;
  }
  ostream &operator<<(ostream &os,Point p){
    os<<fixed<<setprecision(12)<<p.x<<" "<<p.y;
    return os;
  }
}

int n,a[2000],x[2000],y[2000];
using ll=long long;

ll triarea(const Point &a,const Point &b){
  return ll(roundl(abs(a.x*b.y-a.y*b.x)));
}

const Point O={0,0};

ll solve(int id){
  Polygon p(n);
  REP(i,n)p[i]={double(a[i]*(x[i]-x[id])),double(a[i]*(y[i]-y[id]))};
  auto ch=convex_hull(p);
  sort(ALL(ch),[](const Point&p1,const Point&p2){
    if(p1==O)return false;
    if(p2==O)return true;
    return atan2(p1.y,p1.x)<atan2(p2.y,p2.x);
  });
  if(ch.back()==O)ch.pop_back();
  
  //cerr<<id<<":";for(const auto&[xx,yy]:ch)cerr<<"("<<xx<<","<<yy<<")";cerr<<endl;

  ll ans=0;
  int now=0,N=ch.size();
  REP(i,N){
    const auto&v=ch[i];
    if(v==O)continue;
    //cerr<<"I:"<<i<<endl;
    if(v.x*ch[now].y-v.y*ch[now].x<=0)now=i;
    Line l{O,v};
    while(true){
      ans=max(ans,triarea(v,ch[now]));
      //cerr<<"NOW:"<<now<<endl;
      int nxt=(now+1==N?0:now+1);
      if(v.x*ch[nxt].y-v.y*ch[nxt].x>0 and (ch[now]==O||getDistanceLP(l,ch[now])<getDistanceLP(l,ch[nxt])))now=nxt;
      else{
        ans=max(ans,triarea(v,ch[nxt]));
        if(now==i)now=nxt;
        break;
      }
    }
  }
  return ans*a[id];
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  
  cin>>n;
  REP(i,n)cin>>a[i];
  REP(i,n)cin>>x[i]>>y[i];
  REP(i,n)cout<<solve(i)<<"\n";
}
accuracy: 1
time_ms: 1860
memory_kb: 3936
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=1167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}

bool _2d_comp(pair<ll,ll> &l,pair<ll,ll> &r){
	if(l.first==0&&r.first==0) return l.second>r.second;
	if(l.first==0){
		return l.second>0||r.first<0;
	}
	if(r.first==0){
		return !(r.second>0||l.first<0);
	}
	if((l.first<0)^(r.first<0)) return l.first>0;
	return l.first*r.second<l.second*r.first;
}

ll score(pair<ll,ll> a,pair<ll,ll> b){
	return abs(a.first*b.second-a.second*b.first);
}
void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}
bool det(pair<ll,ll> a,pair<ll,ll> b,pair<ll,ll> c);
ll f(int N,vector<pair<ll,ll>> &p);
void solve(){
	int N;
	cin>>N;
	vector<ll> A(N);
	vector<ll> X(N),Y(N);
	rep(i,N) cin>>A[i];
	rep(i,N) cin>>X[i]>>Y[i];
	if(N==3){
		rep(j,2) X[j]-=X[2],Y[j]-=Y[2];
		rep(j,3){
			cout<<A[0]*A[1]*A[2]*score({X[0],Y[0]},{X[1],Y[1]})<<endl;
		}
		return ;
	}
	rep(i,N){
		vector<pair<ll,ll>> n_X;
		rep(j,N){
			if(i==j) continue;
			n_X.push_back({A[j]*(X[j]-X[i]),A[j]*(Y[j]-Y[i])});
		}
		cout<<A[i]*f(N-1,n_X)<<"\n";
	}
}

bool det(pair<ll,ll> a,pair<ll,ll> b,pair<ll,ll> c){
	a.first-=b.first;
	a.second-=b.second;
	b.first-=c.first;
	b.second-=c.second;
	return (0<=a.first*b.second-a.second*b.first);
}

ll f(int N,vector<pair<ll,ll>> &p){
	So(p);
	int k=0;
	vector<pair<ll,ll>> q(N*2);
	rep(i,N){
		while(k>1&&det(q[k-2],q[k-1],p[i])) k--;
		q[k]=p[i];
		k++;
	}
	int t=k;
	rep(j,N-1){
		int i=N-2-j;
		while(k>t&&det(q[k-2],q[k-1],p[i])) k--;
		q[k]=p[i];
		k++;
	}
	k--;
	q.resize(k);
	//for(auto x:q) cout<<x.first<<" "<<x.second<<endl;
	rep(i,k*6) q.push_back(q[i]);
	int left=0;
	int right=0;
	while(q[right].first<=q[right+1].first&&right<3*k) right++;
	vector<int> order(N+2*k);
	rep(i,N+2*k) order[i]=i;
	rep(i,k) p.push_back({q[i+1].first-q[i].first,q[i+1].second-q[i].second});
	rep(i,k) p.push_back({q[i].first-q[i+1].first,q[i].second-q[i+1].second});
	sort(all(order),[&](int L,int R){
		pair<ll,ll> l=p[L],r=p[R];
		return _2d_comp(l,r);
	});
	ll ans=0;
	for(auto a:order){
		if(a>=N+k) right=a-N+1-k;
		else if(a>=N) left=a-N+1;
		if(a>=N) continue;
		//chmax(ans,max(score(p[a],q[left-1]),score(p[a],q[right+1])));
		chmax(ans,max(score(p[a],q[left]),score(p[a],q[right])));
		//chmax(ans,max(score(p[a],q[left+1]),score(p[a],q[right-1])));
		//for(auto x:q) chmax(ans,score(p[i],x));
	}
	return ans;
}
accuracy: 1
time_ms: 910
memory_kb: 3684
final_rank: 14