F - Sigma Problem 解説 by en_translator
We reinterpret \(f(x,y)\) in a more useful form. In the constraints of this problem, \(f(x,y)\) is \(x+y\) if \(x+y < 10^8\) and \(x+y-10^8\) if \(x+y\geq 10^8\).
Thus, the answer can be found by evaluating \(\sum_{i=1}^{N-1}\sum_{j=i+1}^N A_i + A_j\), and then subtracting from it \(10^8 \times\) the number of pairs \((i,j)\ (1\leq i <j\leq N)\) such that \(A_i + A_j\) is greater than or equal to \(10^8\).
Regarding \(\sum_{i=1}^{N-1}\sum_{j=i+1}^N A_i + A_j\), each term is added \((N-1)\) times, so it can be rewritten as \((N-1)\sum_{i=1}^{N} A_i\), which can be found in \(\mathrm{O}(N)\) time.
Next, let us count the integer pairs \((i,j)\ (1\leq i <j\leq N)\) such that \(A_i + A_j\) is greater than or equal to \(10^8\).
The answer does not change by sorting \(A\) in ascending order, so we do so. Then, the minimum \(j\) with \(A_i + A_j\geq 10^8\) monotonically decreases as \(I\) increases. Thus, the number of conforming integer pairs can be counted with the sliding window trick. Be careful not to count too much when \(A_i = 5\times 10^7\).
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> a(n);
for(auto &v : a) cin >> v;
sort(a.begin(), a.end());
int r = n;
ll cnt = 0, res = 0;
for(int i = 0; i < n; i++) {
r = max(r, i + 1);
while(r - 1 > i and a[r - 1] + a[i] >= 100000000) {
r--;
}
cnt += n - r;
}
for(int i = 0; i < n; i++) res += ll(a[i]) * (n - 1);
res -= cnt * 100000000;
cout << res << endl;
}
投稿日時:
最終更新: