Cod sursa(job #3358650)

Utilizator Cezar2009Cezar Mihai Titihazan Cezar2009 Data 18 iunie 2026 22:24:59
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.21 kb
//https://infoarena.ro/problema/secv8

#ifdef _MSC_VER
	#define _CRT_SECURE_NO_WARNINGS
#elif  __GNUC__
	#pragma GCC optimize("Ofast,unroll-loops,inline")
	#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#endif

//#define _USE_MATH_DEFINES

#include <iostream>
#include <fstream>
#include <utility>
#include <cstdint>
//#include <cstdio>
//#include <algorithm>
//#include <vector>
//#include <array>
//#include <list>
//#include <forward_list>
//#include <string>
//#include <cstring>
//#include <cmath>
//#include <bitset>
//#include <queue>
//#include <stack>
//#include <map>
//#include <set>
//#include <unordered_map>
//#include <unordered_set>
//#include <limits>
//#include <climits>
//#include <iomanip>
//#include <tuple>
//#include <numeric>
//#include <chrono>
//#include <memory>
#include <random>

using namespace std;

using int64 = int64_t;
using uint64 = uint64_t;
using int32 = int32_t;
using uint32 = uint32_t;
using int16 = int16_t;
using uint16 = uint16_t;
using pii = pair<int, int>;
using pll = pair<int64, int64>;

#define all(x) (x).begin(), (x).end()
#define allg(x) (x).begin(), (x).end(), greater<int>()
#define sz(x) (int)(x).size()
#define pb push_back
#define eb emplace_back
#define rfor(i, st, dr) for(auto i=(st); i<=(dr); ++i)
#define for0(i,n) for(auto i=0; i<(n); ++i)
#define rfor0(i,n) for(auto i=(n)-1; i>=0; --i)
#define for1(i,n) for(auto i=1; i<=(n); ++i)
#define rfor1(i,n) for(auto i=(n); i>=1; --i)
#define foreach(x,a) for(auto& x : a)
#define cforeach(x,a) for(const auto& x : a)
#define ft first
#define sd second
#define cendl cout << "\n"
#define fendl fout << "\n"
#define FASTIO ios::sync_with_stdio(false); cin.tie(nullptr);

//#define int int64

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

//FILE* fin = fopen("", "r");
//FILE* fout = fopen("", "w");

const int INF = 1e9 + 7;

int getRandom() {
	static random_device rd;
	static mt19937 gen(rd());
	return gen() % (INF - 1);
}

struct Nod {
	Nod(int p_val, int p_pr, int p_s, Nod* p_st, Nod* p_dr)
		: val(p_val), pr(p_pr), s(p_s), bRv(false),
		st(p_st), dr(p_dr) {
	}

	int val; // valoarea
	int s; // cate noduri is sub
	int pr; // prioritatea
	bool bRv; // bool daca trebuie sau nu inversat

	Nod* st, * dr; //nod stanga, dreapta
};

inline int getSize(Nod* nod) {
	if (nod == nullptr)
		return 0;
	return nod->s;
}

inline int getPriority(Nod* nod) {
	if (nod == nullptr)
		return -1;
	return nod->pr;
}

inline void updateSize(Nod* nod) {
	// ce avem stanga + ce avem dreapta + 1
	if (nod) {
		nod->s = getSize(nod->st) + getSize(nod->dr) + 1;
	}
}

inline void update(Nod* nod) {
	if (nod && nod->bRv) {
		swap(nod->st, nod->dr);
		if (nod->st)
			nod->st->bRv ^= 1;
		if (nod->dr)
			nod->dr->bRv ^= 1;
		nod->bRv = false;
	}
}

inline void rotateLeft(Nod* &nod) {
	// la fel ca la dreapta
	Nod* aux = nod->dr;
	nod->dr = aux->st;
	aux->st = nod;

	updateSize(nod);
	nod = aux;
	updateSize(nod);
}

inline void rotateRight(Nod* &nod) {
	Nod* aux = nod->st; // copiem
	nod->st = aux->dr; // punem in stanga fiul drept a copiei
	aux->dr = nod; // mutam copia deasupra nodului

	// calculam sizeul / punem noul nod de sus
	updateSize(nod);
	nod = aux;
	updateSize(nod);
}

void insert(Nod* &nod, int poz, int val, int pr) {
	if (nod == nullptr) {
		nod = new Nod(val, pr, 1, nullptr, nullptr);
		return;
	}

	update(nod);
	if (poz <= getSize(nod->st) + 1) // e in stanga
		insert(nod->st, poz, val, pr);
	else // e in dreapta
		insert(nod->dr, poz - getSize(nod->st) - 1, val, pr);

	if (getPriority(nod->st) > getPriority(nod))
		rotateRight(nod);
	else if (getPriority(nod->dr) > getPriority(nod))
		rotateLeft(nod);

	updateSize(nod);
}

int getValue(Nod* nod, int poz) {
	update(nod);
	if (poz == getSize(nod->st) + 1) // daca este pozitia curenta
		return nod->val;

	if (poz <= getSize(nod->st)) // e in stanga
		return getValue(nod->st, poz);
	else // e in dreapta
		return getValue(nod->dr, poz - getSize(nod->st) - 1);
}

void erase(Nod* &nod, int poz) {
	if (!nod)
		return;

	update(nod);
	if (poz != getSize(nod->st) + 1) { // daca este diferit de pozitia curenta
		if (poz <= getSize(nod->st)) // e in stanga
			erase(nod->st, poz);
		else // e in dreapta
			erase(nod->dr, poz - getSize(nod->st) - 1);
		updateSize(nod);
		return;
	}

	if(nod->st == nullptr && nod->dr == nullptr) {
		delete nod;
		nod = nullptr;
		return;
	}

	if (getPriority(nod->st) > getPriority(nod->dr)) {
		update(nod->st);
		rotateRight(nod);
		erase(nod->dr, getSize(nod->dr->st) + 1);
	}
	else {
		update(nod->dr);
		rotateLeft(nod);
		erase(nod->st, getSize(nod->st->st) + 1);
	}
	updateSize(nod);
}

Nod* split(Nod* &nod, int poz) {
	insert(nod, poz, 100, INF);
	Nod* st = nod->st;
	Nod* dr = nod->dr;

	delete nod;
	nod = st;
	return dr;
}

void join(Nod* &st, Nod* dr) {
	int size = getSize(st) + getSize(dr);
	st = new Nod(100, INF, size + 1, st, dr);
	erase(st, getSize(st->st) + 1);
}

void eraseTree(Nod* &nod) {
	if (!nod)
		return;

	if (nod->st != nullptr)
		eraseTree(nod->st);

	if (nod->dr != nullptr)
		eraseTree(nod->dr);

	delete nod;
	nod = nullptr;
}

void reverseInt(Nod* &nod, int i, int j) {
	Nod* right = split(nod, j + 1);
	Nod* target = split(nod, i);

	if (target) {
		target->bRv = true;
	}

	join(nod, target);
	join(nod, right);
}

void eraseInt(Nod* &nod, int i, int j) {
	Nod* right = split(nod, j + 1);
	Nod* target = split(nod, i);

	eraseTree(target);
	join(nod, right);
}

void print(Nod* nod) {
	if (!nod)
		return;

	update(nod);
	print(nod->st);
	fout << nod->val << " ";
	print(nod->dr);
}

int main()
{
	//FASTIO

	Nod* treap = nullptr;

	int s, t, k, e, i, j;
	char c;

	fin >> s >> t;
	while (s--) {
		fin >> c;

		if (c == 'I') { // Insert
			fin >> k >> e;
			insert(treap, k, e, getRandom());
		}
		else if (c == 'A') { // Acces
			fin >> k;
			fout << getValue(treap, k) << "\n";
		}
		else if (c == 'R') { // Reverse
			fin >> i >> j;
			reverseInt(treap, i, j);
		}
		else { // if (c == 'D') // Delete
			fin >> i >> j;
			eraseInt(treap, i, j);
		}
	}

	print(treap);

	return 0;
}