| # | Time | Username | Problem | Language | Result | Execution time | Memory |
|---|---|---|---|---|---|---|---|
| 1342249 | tutithuybi123 | Triple Peaks (IOI25_triples) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
using namespace std;
long long count_triples(vector<int> H) {
int N = (int)H.size();
long long ans = 0;
vector<vector<int>> L(N), R(N);
// Build L[j] = lengths x such that H[j-x] = x
// and R[j] = lengths y such that H[j+y] = y
for (int p = 0; p < N; ++p) {
int h = H[p];
if (p + h < N) L[p + h].push_back(h);
if (p - h >= 0) R[p - h].push_back(h);
}
// Case 1: largest value is at k
for (int k = 0; k < N; ++k) {
int s = H[k];
int i = k - s;
if (i < 0) continue;
int a = H[i];
if (a <= 0 || a >= s) continue;
int need = s - a;
int j1 = i + a;
if (i < j1 && j1 < k && H[j1] == need) {
ans++;
}
int j2 = k - a;
if (j2 != j1 && i < j2 && j2 < k && H[j2] == need) {
ans++;
}
}
// Case 2: largest value is at i
for (int i = 0; i < N; ++i) {
int s = H[i];
int k = i + s;
if (k >= N) continue;
int a = H[k];
if (a <= 0 || a >= s) continue;
int need = s - a;
int j1 = i + a;
if (i < j1 && j1 < k && H[j1] == need) {
ans++;
}
int j2 = k - a;
if (j2 != j1 && i < j2 && j2 < k && H[j2] == need) {
ans++;
}
}
// Case 3: largest value is at j
for (int j = 0; j < N; ++j) {
int s = H[j];
if (L[j].empty() || R[j].empty()) continue;
if (L[j].size() <= R[j].size()) {
unordered_set<int> have;
have.reserve(R[j].size() * 2 + 1);
for (int y : R[j]) have.insert(y);
for (int x : L[j]) {
int y = s - x;
if (y > 0 && have.find(y) != have.end()) {
ans++;
}
}
} else {
unordered_set<int> have;
have.reserve(L[j].size() * 2 + 1);
for (int x : L[j]) have.insert(x);
for (int y : R[j]) {
int x = s - y;
if (x > 0 && have.find(x) != have.end()) {
ans++;
}
}
}
}
return ans;
}