Cod sursa(job #2875040)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 20 martie 2022 18:10:50
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.07 kb
#include <cstdio>
#include <iostream>
#include <fstream>
#include <random>
#include <chrono>
#include <vector>
#include <numeric>
#include <algorithm>
#include <string>

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);

}


ofstream fout("secv8.out");

const int SKIP_VALUE = -1;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

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 != SKIP_VALUE) {
		fout << 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);

	Node* root = new Node(SKIP_VALUE);

	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);
			fout << access(root, pos + 1) << "\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);
	}
}