| # | Time | Username | Problem | Language | Result | Execution time | Memory |
|---|---|---|---|---|---|---|---|
| 1342254 | tutithuybi123 | Triple Peaks (IOI25_triples) | C++20 | 0 ms | 0 KiB |
#include "triples.h"
#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);
// L[j]: values x such that there exists i = j - x with H[i] = x
// R[j]: values y such that there exists k = j + y with H[k] = 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 height 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];
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 height 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];
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 height 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;
}