Cod sursa(job #2875048)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 20 martie 2022 18:17:59
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.46 kb
#include <cstdio>
#include <chrono>
#include <vector>
#include <numeric>
#include <algorithm>

bool home = true;

using namespace std;

char inBuffer[0x30D40];
unsigned int p = 0x30D3F;

__attribute__((always_inline)) void read(int& num) {

	num = 0x0;
	while (inBuffer[p] < 0x30 | inBuffer[p] > 0x39) {
		++p != 0x30D40 || (fread(inBuffer, 0x1, 0x30D40, stdin), p = 0x0);
	}

	while (inBuffer[p] > 0x2F & inBuffer[p] < 0x3A) {
		num = num * 0xA + inBuffer[p] - 0x30;

		++p != 0x30D40 || (fread(inBuffer, 0x1, 0x30D40, stdin), p = 0x0);
	}
}


__attribute__((always_inline)) void read(char& num) {

	num = inBuffer[p];
	++p != 0x30D40 || (fread(inBuffer, 0x1, 0x30D40, stdin), p = 0x0);

}


char outBuffer[1 << 22];
unsigned int p_out;

__attribute__((always_inline)) void write(unsigned int x)
{
	unsigned int digits = x > 0x3B9AC9FF ? 0xA :
		x > 0x5F5E0FF ? 0x9 :
		x > 0x98967F ? 0x8 :
		x > 0xF423F ? 0x7 :
		x > 0x1869F ? 0x6 :
		x > 0x270F ? 0x5 :
		x > 0x3E7 ? 0x4 :
		x > 0x63 ? 0x3 :
		x > 0x9 ? 0x2 : 0x1;

	for (unsigned int i = ~- digits; ~i; --i)
	{
		outBuffer[p_out + i] = x % 0xA + 0x30;

		x = x / 0xA;
	}

	p_out = p_out + digits; outBuffer[p_out++] = 0x20;
}

__attribute__((always_inline)) void write_ch(char ch)
{
	outBuffer[p_out++] = ch;
}

mt19937 rng(0);

vector<int> priorities(250000 + 7);

struct Node {
	int dim = 1;
	int priority;
	int store;
	bool lazy_tag = false;
	Node* lft = nullptr;
	Node* rgh = nullptr;
	Node(int value) :
		store(value) {
		priority = priorities.back();
		priorities.pop_back();
	}
	~Node() {
		if (lft) delete lft;
		if (rgh) delete rgh;
	}
};

void inner_print(Node* root) {
	if (root && root->lazy_tag) {
		swap(root->lft, root->rgh);
		root->lazy_tag = false;

		if (root->lft) root->lft->lazy_tag ^= 1;
		if (root->rgh) root->rgh->lazy_tag ^= 1;
	}
	if (root->lft) inner_print(root->lft);
	if (root->store != -1) {
                write(root->store);
	}
	if (root->rgh) inner_print(root->rgh);
}


void build(Node* lft, Node* root, Node* rgh) {
	root->lft = lft;
	root->rgh = rgh;
	root->dim = 1;
	if (lft) root->dim += lft->dim;
	if (rgh) root->dim += rgh->dim;
}

int access(Node* root, int pos) {
	if (root && root->lazy_tag) {
		swap(root->lft, root->rgh);
		root->lazy_tag = false;

		if (root->lft) root->lft->lazy_tag ^= 1;
		if (root->rgh) root->rgh->lazy_tag ^= 1;
	}
	int current_pos = (root->lft ? root->lft->dim : 0) + 1;

	if (pos == current_pos) {
		return root->store;
	}

	if (pos < current_pos) {
		return access(root->lft, pos);
	}
	else {
		return access(root->rgh, pos - current_pos);
	}
}

pair<Node*, Node*> split(Node* root, int pos) {
	if (root && root->lazy_tag) {
		swap(root->lft, root->rgh);
		root->lazy_tag = false;

		if (root->lft) root->lft->lazy_tag ^= 1;
		if (root->rgh) root->rgh->lazy_tag ^= 1;
	}
	if (!root) {
		return make_pair(nullptr, nullptr);
	}
	if (pos == 0) {
		return make_pair(nullptr, root);
	}

	if (pos == root->dim) {
		return make_pair(root, nullptr);
	}

	int dim_lft = (root->lft ? root->lft->dim : 0);
	int dim_rgh = (root->rgh ? root->rgh->dim : 0);

	if (pos <= dim_lft) {
		pair<Node*, Node*> pr = split(root->lft, pos);
		build(pr.second, root, root->rgh);
		return make_pair(pr.first, root);
	}
	else {
		pair<Node*, Node*> pr = split(root->rgh, pos - dim_lft - 1);
		build(root->lft, root, pr.first);
		return make_pair(root, pr.second);
	}
}

Node* join(Node* a, Node* b) {
	if (a && a->lazy_tag) {
		swap(a->lft, a->rgh);
		a->lazy_tag = false;

		if (a->lft) a->lft->lazy_tag ^= 1;
		if (a->rgh) a->rgh->lazy_tag ^= 1;
	}

	if (b && b->lazy_tag) {
		swap(b->lft, b->rgh);
		b->lazy_tag = false;

		if (b->lft) b->lft->lazy_tag ^= 1;
		if (b->rgh) b->rgh->lazy_tag ^= 1;
	}


	if (!a) return b;
	if (!b) return a;

	if (a->priority > b->priority) {
		build(a->lft, a, join(a->rgh, b));
		return a;
	}
	else {
		build(join(a, b->lft), b, b->rgh);
		return b;
	}
}

Node* ins(Node* root, int value, int pos) {
	if (root && root->lazy_tag) {
		swap(root->lft, root->rgh);
		root->lazy_tag = false;

		if (root->lft) root->lft->lazy_tag ^= 1;
		if (root->rgh) root->rgh->lazy_tag ^= 1;
	}

	Node* guy = new Node(value);
	pair<Node*, Node*> pr = split(root, pos);

	return join(join(pr.first, guy), pr.second);
}

int main() {
	iota(priorities.begin(), priorities.end(), 0);
	shuffle(priorities.begin(), priorities.end(), rng);


	freopen("secv8.in", "r", stdin);
	freopen("secv8.out", "w", stdout);

	Node* root = new Node(-1);

	int q, _;
	read(q);
	read(_);
	while (q--) {
		char type;
		read(type);
		read(type);

		if (type == 'I') {
			int pos, value;
			read(pos);
			read(value);
			root = ins(root, value, pos);
		}
		if (type == 'A') {
			int pos;
			read(pos);
			write(access(root, pos + 1));
			write_ch('\n');
		}
		if (type == 'R') {
			int l, r;
			read(l);
			read(r);
			l++;
			r++;

			pair<Node*, Node*> pr = split(root, r);
			pair<Node*, Node*> pr2 = split(pr.first, l - 1);
			pr2.second->lazy_tag ^= 1;

			root = join(join(pr2.first, pr2.second), pr.second);
		}
		if (type == 'D') {
			int l, r;
			read(l);
			read(r);
			l++;
			r++;

			pair<Node*, Node*> pr = split(root, r);
			pair<Node*, Node*> pr2 = split(pr.first, l - 1);
			delete pr2.second;

			root = join(pr2.first, pr.second);
		}

	}

	if (root) {
		inner_print(root);
	}

	puts(outBuffer);
}