Submission #1251810

#TimeUsernameProblemLanguageResultExecution timeMemory
1251810LithaniumTriple Peaks (IOI25_triples)C++20
57.01 / 100
2130 ms778156 KiB
#pragma GCC optimize("Ofast,unroll-loops") #include <bits/extc++.h> #include "triples.h" using namespace std; using namespace __gnu_pbds; using ll = long long; mt19937_64 rd(time(0)); ll Hash1[200005]; ll Hash2[200005]; vector<int> construct_range(int M, int K) { M /= 6; M *= 6; vector<int> ans; for (int i = 0; i < M; i += 6) { for (int j:{3, 4, 2, 1, 1, 3}) ans.push_back(j); } return ans; } gp_hash_table<ll, bool> all; vector<int> H; void check(int a, int b, int c) { if (c < 0 or c >= H.size()) return; if (a == b or a == c or b == c) return; array<int, 3> h = {H[a], H[b], H[c]}; array<int, 3> diff = {abs(a-b), abs(a-c), abs(b-c)}; sort(h.begin(), h.end()); sort(diff.begin(), diff.end()); if (h == diff) { all[Hash1[a]^Hash1[b]^Hash1[c]] = 1; } } vector<int> adj[400005]; gp_hash_table<int, __gnu_pbds::null_type> big[400005]; int from[400005]; gp_hash_table<int, int> bruh[400005]; vector<int> cc; ll triangles() { int N = cc.size(); vector<int> order; for (int i = 0; i < N; i ++) order.push_back(i); sort(order.begin(), order.end(), [](const int a, const int b) { return adj[a].size() < adj[b].size(); }); for (int i = 0; i < N; i ++) for (int j:adj[i]) if (make_pair(i, adj[i].size()) < make_pair(j, adj[j].size())) { big[i].insert(j); } ll num = 0; for (int ii = 0; ii < N; ii ++) { int i = order[ii]; for (int j:big[i]) { for (int k:big[j]) if (big[i].find(k) != big[i].end()) { // cout << i << " " << j << " " << k << "\n"; // cout << bruh[i][j] << " " << bruh[i][k] << " " << bruh[j][k] << "\n"; check(bruh[i][j], bruh[i][k], bruh[j][k]); num ++; } } } return num; } ll count_triples(vector<int> h) { ::H = h; int N = H.size(); for (int i = 0; i < N; i ++) Hash1[i] = rd(), Hash2[i] = rd(); for (int i = 0; i < N; i ++) { // Normal case: // Edge with length H[i] connects from i int p1 = i, p2 = i - H[i]; if (p2 >= 0) { check(p1, p2, p1 - H[p2]); check(p1, p2, p1 + H[p2]); check(p1, p2, p2 - H[p2]); check(p1, p2, p2 + H[p2]); } p1 = i, p2 = i + H[i]; if (p2 < N) { check(p1, p2, p1 - H[p2]); check(p1, p2, p1 + H[p2]); check(p1, p2, p2 - H[p2]); check(p1, p2, p2 + H[p2]); } } // count triangles in a graph for (int i = 0; i < N; i ++) { cc.push_back(i - H[i]); cc.push_back(i + H[i]); } sort(cc.begin(), cc.end()); cc.resize(unique(cc.begin(), cc.end()) - cc.begin()); for (int i = 0; i < N; i ++) { int a = lower_bound(cc.begin(), cc.end(), i - H[i]) - cc.begin(); int b = lower_bound(cc.begin(), cc.end(), i + H[i]) - cc.begin(); bruh[a][b] = bruh[b][a] = i; adj[a].push_back(b); adj[b].push_back(a); } triangles(); return (ll)all.size(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...