Cod sursa(job #2875026)

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

bool home = true;

using namespace std;


ifstream fin("secv8.in");
ofstream fout("secv8.out");

/*class InParser {
private:
	FILE* fin;
	char* buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int& n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		}
		else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long& n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		}
		else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};*/

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 push(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;
	}
}

void inner_print(Node* root) {
	assert(root);
	assert(root->dim > 0);
	push(root);

	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) {
	push(root);
	push(lft);
	push(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) {
	push(root);
	assert(root);
	assert(root->dim > 0);
	assert(1 <= pos && pos <= root->dim);

	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) {
	push(root);
	if (!root) {
		assert(pos == 0);
		return make_pair(nullptr, nullptr);
	}
	assert(0 <= pos && pos <= root->dim);
	
	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) {
	push(a);
	push(b);
	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) {
	push(root);


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


	Node* root = new Node(SKIP_VALUE);

	int q, _;
	fin >> q >> _;
	while (q--) {
		string type;
		fin >> type;
		if (type == "I") {
			int pos, value;
			fin >> pos >> value;
			root = ins(root, value, pos);
		}
		if (type == "A") {
			int pos;
			fin >> pos;
			fout << access(root, pos + 1) << "\n";
		}
		if (type == "R") {
			int l, r;
			fin >> l >> 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;
			fin >> l >> 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);
	}
}