제출 #1252220

#제출 시각아이디문제언어결과실행 시간메모리
1252220EJIC_B_KEDAXTriple Peaks (IOI25_triples)C++20
70 / 100
1423 ms100104 KiB
#include "triples.h" #include <bits/stdc++.h> using namespace std; using ll = long long; struct mst { vector<vector<int>> st; size_t sz; mst(vector<int> a) { sz = 1; while (sz < a.size()) { sz <<= 1; } st.resize(2 * sz); for (int i = 0; i < a.size(); i++) { st[sz + i].push_back(a[i]); } for (int i = sz - 1; i > 0; i--) { st[i].resize(st[2 * i].size() + st[2 * i + 1].size()); ranges::merge(st[2 * i], st[2 * i + 1], st[i].begin()); } } int get_same(int l, int r, int v) { l += sz; r += sz; int res = 0; while (l <= r) { if (l & 1) { res += ranges::upper_bound(st[l], v) - ranges::lower_bound(st[l], v); l++; } if (~r & 1) { res += ranges::upper_bound(st[r], v) - ranges::lower_bound(st[r], v); r--; } l >>= 1; r >>= 1; } return res; } }; ll count_triples(vector<int> h) { int n = h.size(); vector<int> ff = h, ss = h; vector<int> prev(n), next(n); for (int i = 0; i < n; i++) { ff[i] -= i; ss[i] += i; } map<int, int> mp; for (int i = 0; i < n; i++) { if (mp.find(ff[i]) == mp.end()) { prev[i] = -1; } else { prev[i] = mp[ff[i]]; } mp[ff[i]] = i; } mp.clear(); for (int i = n - 1; i >= 0; i--) { if (mp.find(ss[i]) == mp.end()) { next[i] = n; } else { next[i] = mp[ss[i]]; } mp[ss[i]] = i; } mst mst1(ff), mst2(ss); ll ans = 0; auto check1 = [&](int i, int j, int k) -> bool { vector<int> x = {abs(i - j), abs(j - k), abs(k - i)}, y = {h[i], h[j], h[k]}; ranges::sort(x); ranges::sort(y); return x == y; }; auto check2 = [&](int i, int j, int k) -> bool { if (abs(k - i) == h[j] && abs(i - j) == h[k] && abs(j - k) == h[i]) return false; return check1(i, j, k); }; auto srt = [](tuple<int, int, int> t) -> tuple<int, int, int> { vector<int> x = {get<0>(t), get<1>(t), get<2>(t)}; ranges::sort(x); return {x[0], x[1], x[2]}; }; set<tuple<int, int, int>> simp; for (int i = 0; i < n; i++) { if (i - h[i] >= 0) { int j = i - h[i]; if (j - h[j] >= 0) { int l = j - h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (j + h[j] < n) { int l = j + h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (i - h[j] >= 0) { int l = i - h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (i + h[j] < n) { int l = i + h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } } if (i + h[i] < n) { int j = i + h[i]; if (j - h[j] >= 0) { int l = j - h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (j + h[j] < n) { int l = j + h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (i - h[j] >= 0) { int l = i - h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } if (i + h[j] < n) { int l = i + h[j]; if (check2(i, j, l)) { simp.insert(srt({i, j, l})); } } } } ans += simp.size(); simp.clear(); for (int i = 0; i < n; i++) { if (mst1.get_same(0, i, ff[i]) < mst2.get_same(i, n - 1, ss[i])) { int cur = prev[i]; while (cur != -1) { if (i + h[cur] < n && check1(cur, i, i + h[cur])) { ans++; } cur = prev[cur]; } } else { int cur = next[i]; while (cur != n) { if (i - h[cur] >= 0 && check1(i - h[cur], i, cur)) { ans++; } cur = next[cur]; } } } return ans; } vector<int> construct_range(int n, int _K) { n--; const int D = 362, CD = 181; vector<int> ans(n, 0); for (int i = 0; i < CD; i++) { for (int j = 0; j < D; j++) { ans[i * D + j] = (n + 1) / 4 - D / 2 + j; } } for (int i = 0; i < CD; i++) { for (int j = 0; j < D; j++) { ans[n - 1 - (i * D + j)] = (n + 1) / 4 - D / 2 + j - 2 * i; } } set<int> good; for (int i = 0; i < CD; i++) { for (int j = 0; j < CD; j++) { int hui = (n - 1 + (i - j) * D - 2 * j) / 2; if (hui >= CD * D && hui < n - CD * D) { ans[hui] = ans[i * D] + hui - i * D; good.insert(hui); } } } cout << good.size() << '\n'; for (int i = 0; i < n; i++) { ans[i] = max(min(ans[i], n - 1), 1); } return ans; }
#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...