ICPC 2020
ICPC 2020

G. Opportunity Cost

As with most types of products, buying a new phone can be difficult. One of the main challenges is that there are a lot of different aspects of the phone that you might care about, such as its price, its performance, and how user-friendly the phone is. Typi...

Updated May 21, 2026
Track ICPC
Year 2020
Statement Text + PDF
TeXC++Statement textStatement PDF

Problem Statement

Formatted from the contest statement text, with sample tests broken out into copyable blocks.

Time limit 5 seconds

As with most types of products, buying a new phone can be difficult. One of the main challenges is that there are a lot of different aspects of the phone that you might care about, such as its price, its performance, and how user-friendly the phone is. Typically, there will be no single phone that is simultaneously the best at all of these things: the cheapest phone, the most powerful phone, and the most user-friendly phone will likely be different phones. Thus when buying a phone, you are forced to make some sacrifices by balancing the different aspects you care about against each other and choosing the phone that achieves the best compromise (where “best” of course depends on what your priorities happen to be). One way of measuring this sacrifice is known as the opportunity cost, which (for the purposes of this problem) we define as follows. Suppose that you have bought a phone with price x, performance y, and user-friendliness z. For sim- plicity, we assume that these three values are measured on a comparable numeric scale where higher is better. If there are n available phones, and the values (xi , yi , zi ) represent the (price, performance, user-friendliness) of the ith phone, then the opportunity cost of your phone is defined as

max (max(xi − x, 0) + max(yi − y, 0) + max(zi − z, 0)) .
1≤i≤n

Write a program that, given the list of available phones, finds a phone with the minimum opportunity cost.

Input

The first line of input contains an integer n (2 ≤ n ≤ 200 000), the number of phones considered. Following that are n lines. The ith of these lines contains three integers xi , yi , and zi , where xi is the price, yi is the performance, and zi is the user-friendliness of the ith phone (1 ≤ xi , yi , zi ≤ 109 ).

Output

Output a single line containing two integers: the smallest possible opportunity cost and an integer be- tween 1 and n indicating the phone achieving that opportunity cost. If there are multiple such phones, output the one with the smallest index.

Sample Tests

Sample 1
Sample Input
 4
 20 5 5
 5 20 5
 5 5 20
 10 10 10
Sample Output
10 4
Sample 2
Sample Input
4
15 15 5
5 15 15
15 5 15
10 10 10
Sample Output
10 1

Editorial

The solution write-up is rendered from the LaTeX source, with equations kept live through MathJax.

Key Observations

  • For a fixed phone $(x,y,z)$ and a fixed competitor $(x_i,y_i,z_i)$, \[ \max(x_i-x,0)+\max(y_i-y,0)+\max(z_i-z,0) \] is the sum of the positive coordinate differences.

  • That is exactly \[ \max_{S \subseteq \{x,y,z\}} \left( \sum_{d \in S} d_i - \sum_{d \in S} d \right), \] because for each coordinate we either include its difference (if positive) or exclude it (if negative).

  • Therefore the opportunity cost of phone $(x,y,z)$ is \[ \max_{\emptyset \ne S \subseteq \{x,y,z\}} \left( M_S - \sum_{d \in S} d \right), \] where \[ M_S = \max_i \sum_{d \in S} d_i. \]

  • There are only $2^3-1=7$ nonempty subsets, so we can precompute all values $M_S$ in one pass and then evaluate every phone in constant time.

Algorithm

  1. Number the three dimensions by bits $0,1,2$. For every nonempty mask mask from $1$ to $7$, let \[ M_{\texttt{mask}} = \max_i \sum_{\texttt{bit} \in \texttt{mask}} \text{value}_{i,\texttt{bit}}. \]

  2. Read all phones and update these $7$ maxima.

  3. For each phone $p$, compute \[ \max_{\texttt{mask}=1}^{7} \left( M_{\texttt{mask}} - \sum_{\texttt{bit} \in \texttt{mask}} p_{\texttt{bit}} \right). \] This is exactly its opportunity cost.

  4. Keep the minimum pair \[ (\text{cost}, \text{index}) \] lexicographically, so ties are broken by the smallest index automatically.

Correctness Proof

We prove that the algorithm returns the correct answer.

Lemma 1.

For any real numbers $a,b,c$, \[ \max(a,0)+\max(b,0)+\max(c,0) = \max_{S \subseteq \{1,2,3\}} \sum_{j \in S} v_j, \] where $(v_1,v_2,v_3)=(a,b,c)$.

Proof.

For each coordinate $v_j$, adding it helps exactly when $v_j > 0$ and hurts when $v_j < 0$. So the maximum subset sum is obtained by taking precisely the positive coordinates, and its value is $\max(a,0)+\max(b,0)+\max(c,0)$. □

Lemma 2.

For a fixed phone $p=(x,y,z)$, its opportunity cost equals \[ \max_{\emptyset \ne S \subseteq \{x,y,z\}} \left( M_S - \sum_{d \in S} d \right). \]

Proof.

For any competitor phone $i$, apply Lemma 1 to \[ a = x_i-x,\qquad b = y_i-y,\qquad c = z_i-z. \] Then \[ \max(x_i-x,0)+\max(y_i-y,0)+\max(z_i-z,0) = \max_S \left( \sum_{d \in S} d_i - \sum_{d \in S} d \right). \] Now maximize over all competitors $i$: \[ \max_i \max_S (\cdots) = \max_S \max_i (\cdots) = \max_S \left( M_S - \sum_{d \in S} d \right). \] The empty subset contributes $0$, so restricting to nonempty subsets does not change the maximum. □

Lemma 3.

For every phone $p$, the algorithm computes its exact opportunity cost.

Proof.

The preprocessing step computes every value $M_S$ exactly by definition. Then for phone $p$ the algorithm evaluates the expression from Lemma 2 over all seven nonempty subsets. Hence the maximum it obtains is exactly the opportunity cost of $p$. □

Theorem.

The algorithm outputs the correct answer for every valid input.

Proof.

By Lemma 3, the algorithm computes the exact opportunity cost of every phone. It then chooses the minimum pair $(\text{cost}, \text{index})$, so it returns the smallest possible opportunity cost and, among all phones achieving it, the smallest index. Therefore the output is correct. □

Complexity Analysis

There are only $7$ nonempty subsets. So both the preprocessing pass and the evaluation pass take $O(7n)=O(n)$ time.

The stored phone list uses $O(n)$ memory.

Implementation Notes

  • Using bitmasks $1 \dots 7$ is a convenient way to enumerate the seven nonempty subsets.

  • All sums fit safely in 64-bit integers.

  • The lexicographic minimum of (cost, index) handles the required tie-break automatically.

Code

C++ solution used for this page.

C++

Clean code view with a raw-file link when you want the original source.

Raw file
#include <bits/stdc++.h>
using namespace std;

namespace {

void solve() {
    int n;
    cin >> n;

    vector<array<long long, 3>> phones(n);
    array<long long, 8> best_sum;
    best_sum.fill(0);

    for (int i = 0; i < n; ++i) {
        cin >> phones[i][0] >> phones[i][1] >> phones[i][2];
        for (int mask = 1; mask < 8; ++mask) {
            long long sum = 0;
            for (int bit = 0; bit < 3; ++bit) {
                if (mask & (1 << bit)) {
                    sum += phones[i][bit];
                }
            }
            best_sum[mask] = max(best_sum[mask], sum);
        }
    }

    pair<long long, int> answer = {LLONG_MAX, -1};
    for (int i = 0; i < n; ++i) {
        long long cost = 0;
        for (int mask = 1; mask < 8; ++mask) {
            long long sum = 0;
            for (int bit = 0; bit < 3; ++bit) {
                if (mask & (1 << bit)) {
                    sum += phones[i][bit];
                }
            }
            cost = max(cost, best_sum[mask] - sum);
        }
        answer = min(answer, {cost, i + 1});
    }

    cout << answer.first << ' ' << answer.second << '\n';
}

}  // namespace

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

    solve();
    return 0;
}

Source Files and Assets

Raw files are still available here when you want the original TeX, C++, or statement assets.

Show raw files