Pagini recente » Cod sursa (job #319607) | Cod sursa (job #3205511) | Cod sursa (job #2805588) | Cod sursa (job #2544750) | Cod sursa (job #3251024)
#pragma GCC optimize("Ofast")
#define LIBCXX_ENABLE_THREADS OFF
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
#ifndef LOCAL
ifstream in("secv8.in");
ofstream out("secv8.out");
#define cin in
#define cout out
#endif // LOCAL
#include <iostream>
#include <memory>
#include <cassert>
#include <vector> // For std::vector
// Modified bump_allocator
template <typename T>
class bump_allocator {
public:
using value_type = T;
struct buffer_t {
char* data;
std::size_t size;
std::size_t offset;
};
// Static vector of buffers shared among all instances
static std::vector<buffer_t> buffers;
static constexpr std::size_t initial_buffer_size = 2 * 1024 * 1024 * sizeof(T);
// Static initialization flag
static bool initialized;
bump_allocator() {
if (!initialized) {
allocate_new_buffer(initial_buffer_size);
initialized = true;
}
}
// Copy constructor for rebind mechanism
template <typename U>
bump_allocator(const bump_allocator<U>&) noexcept {
if (!initialized) {
allocate_new_buffer(initial_buffer_size);
initialized = true;
}
}
// Allocate memory for n objects of type T
T* allocate(std::size_t n) {
size_t space_required = n * sizeof(T);
// Try to allocate in the current buffer
buffer_t& current_buffer = buffers.back();
if (current_buffer.offset + space_required <= current_buffer.size) {
T* result = reinterpret_cast<T*>(current_buffer.data + current_buffer.offset);
current_buffer.offset += space_required;
return result;
} else {
// Allocate a new buffer with increased size (e.g., double the current size)
std::size_t new_buffer_size = std::max(space_required, current_buffer.size * 2);
allocate_new_buffer(new_buffer_size);
// Now allocate from the new buffer
return allocate(n); // Recursive call should succeed now
}
}
// Deallocate is a no-op for a bump allocator
void deallocate(T*, std::size_t) {
// No-op
}
// Resets the allocator (only way to free all memory)
static void reset() {
// Free all buffers
for (auto& buffer : buffers) {
delete[] buffer.data;
}
buffers.clear();
initialized = false;
}
// Construct an object of type T in allocated memory
template <typename U, typename... Args>
void construct(U* p, Args&&... args) {
::new ((void*)p) U(std::forward<Args>(args)...); // Placement new
}
// Destroy an object of type T
template <typename U>
void destroy(U* p) {
p->~U(); // Explicitly call the destructor
}
// Comparison operators (necessary for allocator compatibility)
bool operator==(const bump_allocator&) const noexcept {
return true; // All instances are considered equal (stateless)
}
bool operator!=(const bump_allocator& other) const noexcept {
return !(*this == other);
}
// Rebind allocator to a different value type (required for allocator compatibility)
template <typename U>
struct rebind {
using other = bump_allocator<U>;
};
private:
// Allocate a new buffer and add it to the buffers vector
static void allocate_new_buffer(std::size_t buffer_size) {
buffer_t new_buffer;
new_buffer.data = new char[buffer_size];
new_buffer.size = buffer_size;
new_buffer.offset = 0;
buffers.push_back(new_buffer);
}
};
// Initialize static variables
template <typename T>
std::vector<typename bump_allocator<T>::buffer_t> bump_allocator<T>::buffers;
template <typename T>
bool bump_allocator<T>::initialized = false;
// Main function
int main() {
#ifndef LOCAL
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#endif // LOCAL
rope<int, bump_allocator<int>> s; // Use the updated bump allocator here
int k, c;
cin >> k >> c;
while (k--) {
char t;
cin >> t;
if (t == 'I') {
int p, x;
cin >> p >> x;
p--;
s.insert(p, x);
s.insert(s.size() - p, x);
}
if (t == 'A') {
int p;
cin >> p;
cout << s[p - 1] << '\n';
}
if (t == 'R') {
int l, r;
cin >> l >> r;
l--;
r--;
s = s.substr(0, l) + s.substr(s.size() - r - 1, r - l + 1) +
s.substr(r + 1, s.size() - 2 * r - 2) + s.substr(l, r - l + 1) +
s.substr(s.size() - l, l);
}
if (t == 'D') {
int l, r;
cin >> l >> r;
l--;
r--;
s.erase(s.size() - r - 1, r - l + 1);
s.erase(l, r - l + 1);
}
#ifdef LOCAL
cerr << "\t\tS: ";
for (auto e : s) cerr << e << " ";
cerr << endl;
#endif // LOCAL
}
s = s.substr(0, s.size() / 2);
for (auto e : s) cout << e << " ";
cout << '\n';
// When done with all allocations
bump_allocator<int>::reset();
return 0;
}