제출 #726099

#제출 시각아이디문제언어결과실행 시간메모리
726099Alex_tz307코끼리 (Dancing Elephants) (IOI11_elephants)C++17
100 / 100
6639 ms8648 KiB
#include <bits/stdc++.h> #include "elephants.h" using namespace std; const int kN = 1e5 + 5e4; const int bucketSize = 1e3; const int kBuckets = 150; int n, len, a[kN], bucket[kN], indexInBucket[kN]; int updates, auxSize, auxIndices[kN]; class bucket_t { private: int N, indices[2 * bucketSize]; int req[2 * bucketSize], maxReach[2 * bucketSize]; public: void reset() { N = 0; } bool isEmpty() { return N == 0; } int getSize() { return N; } int last() { return a[indices[N - 1]]; } void add(int index) { indices[N++] = index; } void addAll() { for (int i = 0; i < N; ++i) { auxIndices[auxSize++] = indices[i]; } } int jumps(int index) { return req[index]; } int furthest(int index) { return maxReach[index]; } void build() { int r = N - 1; for (int l = N - 1; l >= 0; --l) { while (a[indices[r]] - a[indices[l]] > len) { r -= 1; } if (r == N - 1) { req[l] = 1; maxReach[l] = a[indices[l]] + len; } else { req[l] = req[r + 1] + 1; maxReach[l] = maxReach[r + 1]; } } } void rem(int pos) { for (int i = pos; i < N - 1; ++i) { indices[i] = indices[i + 1]; indexInBucket[indices[i]] = i; } N -= 1; build(); } void ins(int index) { int ptr = N - 1; while (ptr >= 0 && a[index] < a[indices[ptr]]) { ptr -= 1; } for (int i = N; i > ptr + 1; --i) { indices[i] = indices[i - 1]; indexInBucket[indices[i]] = i; } indices[ptr + 1] = index; indexInBucket[index] = ptr + 1; N += 1; build(); } int upperBound(int x) { int l = -1, r = N; while (r - l > 1) { int mid = (l + r) / 2; if (mid != -1 && (mid == N || x < a[indices[mid]])) { r = mid; } else { l = mid; } } return r; } } buckets[kBuckets]; void init(int N, int L, int X[]) { n = N; len = L; for (int i = 0; i <= (n - 1) / bucketSize; ++i) { buckets[i].reset(); } for (int i = 0; i < n; ++i) { a[i] = X[i]; bucket[i] = i / bucketSize; indexInBucket[i] = i % bucketSize; buckets[i / bucketSize].add(i); } for (int i = 0; i <= (n - 1) / bucketSize; ++i) { buckets[i].build(); } } void rebuild() { auxSize = 0; for (int i = 0; i <= (n - 1) / bucketSize; ++i) { buckets[i].addAll(); buckets[i].reset(); } for (int i = 0; i < n; ++i) { bucket[auxIndices[i]] = i / bucketSize; indexInBucket[auxIndices[i]] = i % bucketSize; buckets[i / bucketSize].add(auxIndices[i]); } for (int i = 0; i <= (n - 1) / bucketSize; ++i) { buckets[i].build(); } } int query() { int res = 0; int reach = -1; for (int i = 0; i <= (n - 1) / bucketSize; ++i) { if (!buckets[i].isEmpty() && reach < buckets[i].last()) { int index = buckets[i].upperBound(reach); res += buckets[i].jumps(index); reach = buckets[i].furthest(index); } } return res; } int update(int index, int x) { buckets[bucket[index]].rem(indexInBucket[index]); a[index] = x; bucket[index] = -1; for (int i = 0; i <= (n - 1) / bucketSize && bucket[index] == -1; ++i) { if (!buckets[i].isEmpty() && x <= buckets[i].last()) { bucket[index] = i; } } if (bucket[index] == -1) { bucket[index] = (n - 1) / bucketSize; } buckets[bucket[index]].ins(index); updates += 1; if (updates == bucketSize) { rebuild(); updates = 0; } return query(); }
#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...