//#include "triples.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
long long count_triples(vector<int> H) {
vector<int> h;
for (auto a : H) h.pb(a);
set<vector<int>> ST;
int n = H.size();
long long cnt = 0;
// --- six direct patterns (safe bounds + explicit i<j<k checks) ---
for (int i = 0; i < n; ++i) {
int j = i + h[i];
if (j < n) {
int k = j + h[j];
if (k < n && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
for (int i = 0; i < n; ++i) {
int j = i + h[i];
if (j < n) {
int k = i + h[j];
if (k < n && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
for (int i = 0; i < n; ++i) {
int k = i + h[i];
if (k < n) {
int j = k - h[k];
if (j >= 0 && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
for (int i = 0; i < n; ++i) {
int k = i + h[i];
if (k < n) {
int j = i + h[k];
if (j < n && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
for (int j = 0; j < n; ++j) {
int i = j - h[j];
if (i >= 0) {
int k = j + h[i];
if (k < n && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
for (int j = 0; j < n; ++j) {
int k = j + h[j];
if (k < n) {
int i = k - h[k];
if (i >= 0 && i < j && j < k) {
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
}
// --- Optimized handling of the symmetric case (no O(g^2) pairs) ---
// Build groups by s = idx + H[idx] and membership hash-sets.
int Smax = 2 * n + 5;
vector<vector<int>> groups(Smax);
unordered_map<int, unordered_set<int>> groups_set; groups_set.reserve(n * 2);
for (int idx = 0; idx < n; ++idx) {
int s = idx + h[idx];
groups[s].pb(idx);
}
for (int s = 0; s < Smax; ++s) {
if (!groups[s].empty()) {
unordered_set<int> st; st.reserve(groups[s].size() * 2 + 1);
for (int x : groups[s]) st.insert(x);
groups_set[s] = std::move(st);
}
}
// For each j, iterate i in groups[j] (i + H[i] == j).
// For each such i compute k = i + H[j] and check if k in groups[s_j], then validate triple.
for (int j = 0; j < n; ++j) {
int s_j = j + h[j];
if (s_j < 0 || s_j >= Smax) continue;
if (groups[j].empty()) continue; // no i such that i + H[i] == j
if (groups_set.find(s_j) == groups_set.end()) continue; // no k with s = s_j
auto &target_set = groups_set[s_j];
for (int i : groups[j]) {
int k = i + h[j];
if (k <= j || k >= n) continue; // need i < j < k
if (target_set.find(k) == target_set.end()) continue;
// final verification (multiset check) to be safe
multiset<int> st = {H[i], H[j], H[k]};
if (st.find(j - i) != st.end()) st.erase(st.find(j - i));
if (st.find(k - i) != st.end()) st.erase(st.find(k - i));
if (st.find(k - j) != st.end()) st.erase(st.find(k - j));
if (st.empty()) ST.insert({i, j, k});
}
}
cnt = (long long)ST.size();
return cnt;
}
vector<int> construct_range(int M, int K) {
}
Compilation message (stderr)
triples.cpp: In function 'std::vector<int> construct_range(int, int)':
triples.cpp:145:1: warning: no return statement in function returning non-void [-Wreturn-type]
145 | }
| ^| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |