Submission #1224871

#TimeUsernameProblemLanguageResultExecution timeMemory
1224871ericl23302Dancing Elephants (IOI11_elephants)C++20
100 / 100
5362 ms5956 KiB
#include "elephants.h" #include <bits/stdc++.h> using namespace std; const int k = 400; int n, l, cnt = 0; vector<int> positions; vector<vector<int>> buckets; vector<int> bucketStarts, bucketEnds; vector<vector<pair<int, int>>> bucketDps; void doDp(int bucket) { // cout << "Do DP: " << bucket << endl; vector<int> &curBucket = buckets[bucket]; vector<pair<int, int>> &curDp = bucketDps[bucket]; int sz = curBucket.size(); if (!sz) { bucketStarts[bucket] = (bucket ? bucketStarts[bucket - 1] : -1); bucketEnds[bucket] = (bucket ? bucketEnds[bucket - 1] : -1); return; } curDp.assign(sz, {0, 0}); curDp[sz - 1] = {1, curBucket[sz - 1] + l}; int j = sz - 1; for (int i = sz - 2; i >= 0; --i) { while (curBucket[j] > curBucket[i] + l) --j; if (j < sz - 1) curDp[i] = {1 + curDp[j + 1].first, curDp[j + 1].second}; else curDp[i] = {1, curBucket[i] + l}; } bucketStarts[bucket] = curBucket[0]; bucketEnds[bucket] = curBucket[sz - 1]; } void build() { buckets.clear(); bucketStarts.clear(); bucketEnds.clear(); bucketDps.clear(); vector<int> elephants(n); for (int i = 0; i < n; ++i) elephants[i] = positions[i]; sort(elephants.begin(), elephants.end()); buckets.resize((n - 1) / k + 1); for (int i = 0; i < n; ++i) buckets[i / k].push_back(elephants[i]); for (int i = 0; i < buckets.size(); ++i) bucketDps.push_back({}), bucketStarts.push_back(-1), bucketEnds.push_back(-1), doDp(i); } void print() { cout << n << ' ' << l << ' ' << cnt << endl; cout << "Positions: " << endl; for (int &i : positions) cout << i << ' '; cout << endl; cout << "Buckets: " << endl; for (auto &i : buckets) { for (int &j : i) cout << j << ' '; cout << endl; } cout << "Bucket Starts: " << endl; for (int &i : bucketStarts) cout << i << ' '; cout << endl; cout << "Bucket Ends: " << endl; for (int &i : bucketEnds) cout << i << ' '; cout << endl; cout << "Bucket DP: " << endl; for (auto &i : bucketDps) { for (auto &j : i) cout << j.first << ' ' << j.second << " "; cout << endl; } } int solve() { // print(); int curRes = 0, curEnd = 0; int bucketCount = buckets.size(); for (int i = 0; i < bucketCount; ++i) { if (!buckets[i].empty()) { curRes = bucketDps[i][0].first, curEnd = bucketDps[i][0].second; break; } } // cout << "SOLVE: " << endl; // cout << curRes << ' ' << curEnd << endl; int j = 0; while (j < bucketCount - 1) { ++j; // cout << "J(0): " << j << endl; if (curEnd >= bucketEnds[j]) continue; // cout << "J(1): " << j << endl; int pos = upper_bound(buckets[j].begin(), buckets[j].end(), curEnd) - buckets[j].begin(); // cout << "POS: " << pos << endl; curRes += bucketDps[j][pos].first; curEnd = bucketDps[j][pos].second; // cout << curRes << ' ' << curEnd << endl; } return curRes; } void init(int N, int L, int X[]) { n = N; l = L; for (int i = 0; i < N; ++i) positions.push_back(X[i]); } int update(int i, int y) { if (cnt % k == 0) build(); int bucketCount = buckets.size(); int a = 0, b = 0; while (a < bucketCount) { if (bucketEnds[a] >= positions[i]) break; ++a; } while (b < bucketCount) { if (bucketEnds[b] >= y) break; ++b; } b = min(b, bucketCount - 1); buckets[a].erase(lower_bound(buckets[a].begin(), buckets[a].end(), positions[i])); positions[i] = y; buckets[b].push_back(positions[i]); sort(buckets[b].begin(), buckets[b].end()); doDp(a); if (a != b) doDp(b); ++cnt; return solve(); }
#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...