template <typename T, classCmp> ostream& operator <<(ostream& out, const unordered_set<T, Cmp>& a) { out << "{"; bool first = true; for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "}"; return out; }
template <typename U, typename T, classCmp> ostream& operator <<(ostream& out, const unordered_map<U, T, Cmp>& a) { out << "{"; bool first = true; for (auto& p : a) { out << (first ? "" : ", "); out << p.first << ":" << p.second; first = 0;} out << "}"; return out; }
intsolve(){ int N ; cin >> N; vector<int> nums(N); for (int i = 0; i < N; ++i) { cin >> nums[i]; } if (N <= 3) return N; vector<int> diff(N); diff[0] = 0; for (int i = 1; i < N; ++i) { diff[i] = nums[i] - nums[i-1]; } int hi = N + 1; int lo = 4; auto binary = [&](ll lo, ll hi, function<bool(const ll)> predicate) -> int { // return first true while (lo < hi) { ll mid = lo + (hi - lo) / 2; if (predicate(mid)) { hi = mid; } else { lo = mid + 1; } } return lo; }; auto pred = [&](const ll x) -> bool { unordered_map<int, unordered_set<int>> cnt; map<int, unordered_set<int>, greater<int>> reverseCnt; // cnt->value, cnt->count auto addCnt = [&](constint i) -> void { cnt[diff[i]].insert(i); reverseCnt[cnt[diff[i]].size()].insert(diff[i]); reverseCnt[cnt[diff[i]].size() - 1].erase(diff[i]); if (reverseCnt[cnt[diff[i]].size() - 1].empty()) { reverseCnt.erase(cnt[diff[i]].size() - 1); } }; auto eraseCnt = [&](constint i) -> void { auto& first = cnt[diff[i]]; first.erase(first.find(i)); reverseCnt[cnt[diff[i]].size() + 1].erase(diff[i]); if (reverseCnt[cnt[diff[i]].size() + 1].empty()) { reverseCnt.erase(cnt[diff[i]].size() + 1); } if (first.empty()) { cnt.erase(diff[i]); } reverseCnt[cnt[diff[i]].size()].insert(diff[i]); };
for (int i = 1; i < x; ++i) { addCnt(i); } auto check = [&](constint lastIdx) -> bool { // cout << lastIdx << " ... " << cnt << " " << maxDiffIndex << " " << maxDiffValue << endl; auto it = reverseCnt.begin(); constint maxDiffValue = it->first; constint maxDiffIndex = *(it->second.begin()); if (maxDiffValue == x - 1) returntrue; elseif (maxDiffValue == x - 2 || maxDiffValue == x - 3) { vector<int> index; index.reserve(2); for (constauto& p : cnt) { if (p.first != maxDiffIndex) { for (constauto& idx : p.second) { index.push_back(idx); } } } if (maxDiffValue == x - 2) { if (index[0] == lastIdx || index[0] == lastIdx - x + 2) returntrue; elsereturnfalse; } elseif (maxDiffValue == x - 3) { if (index[1] < index[0]) { swap(index[0], index[1]); } if (index[0] + 1 != index[1]) returnfalse; if (nums[index[1]] - nums[index[0] - 1] == maxDiffIndex * 2) returntrue; elsereturnfalse; } elsereturnfalse; } elsereturnfalse; }; // cout << "Debug: " << maxDiffValue << endl; if (check(x-1)) returnfalse; // if check for (int i = x; i < N; ++i) { // cout << "before: " << cnt ; eraseCnt(i - x + 1); addCnt(i); // cout << "after: " << cnt << " !!! "; if (check(i)) returnfalse; } returntrue; }; // for (int i = 4; i < hi; ++i) { // cout << i << ":" << pred(i) << " "; // } returnbinary(lo, hi, pred) - 1; }
intmain(){ int T; cin >> T; for (int i = 0; i < T; ++i) { cout << "Case #" << i + 1 << ": "; cout << solve(); cout << endl; } return0; }
时间复杂度: O(N log N log N),
空间复杂度: O(N).
按理说 N = 10 ^ 5 不会超时,然而大的case还是TLE了。可能是被卡常数了。
看了官方题解,时间复杂度是O(N)。多了两个log还是不行呀。