Cod sursa(job #2977964)

Utilizator JustinTrudeauBarack Obama JustinTrudeau Data 12 februarie 2023 18:14:40
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.69 kb
#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <numeric>

using namespace std;


struct MetaData {
	int index;
	int len;
};

struct Smart {
	vector<bool> rev;
	vector<vector<int>> Data;
	vector<MetaData> metaData;
	const int S = 300;
	int sz = 0;


	void unpack(int index) {
		if (rev[index]) {
			rev[index] = 0;
			reverse(Data[index].begin(), Data[index].end());
		}
	}

	int placeData(vector<int>& v) {
		for (int i = 0; i < (int)Data.size(); i++) {
			if (Data[i].empty()) {
				Data[i] = v;
				rev[i] = 0;
				return i;
			}
		}
		Data.push_back(v);
		rev.push_back(0);
		return (int)Data.size() - 1;
	}

	void split(int k) {
		vector<MetaData> newMetaData;
		// splits between k and k + 1
		if (k + 1 == sz) return;
		int sum = 0;
		for (int i = 0; i < (int)metaData.size(); i++) {
			if (sum + metaData[i].len - 1 == k) return;
			if (k <= sum + metaData[i].len - 2) {
				unpack(metaData[i].index);
				vector<int> bck;
				for (int p = k + 1; p <= sum + metaData[i].len - 1; p++) {
					bck.push_back(Data[metaData[i].index][p - sum]);
				}

				for (int p = k + 1; p <= sum + metaData[i].len - 1; p++) {
					Data[metaData[i].index].pop_back();
				}

				int pos = placeData(bck);
				
				newMetaData.push_back({ metaData[i].index, (int)Data[metaData[i].index].size() });
				newMetaData.push_back({ pos, (int)bck.size() });


				for (int j = i + 1; j < (int)metaData.size(); j++) {
					newMetaData.push_back(metaData[j]);
				}
				metaData = newMetaData;
				return;
			}
			sum += metaData[i].len;
			newMetaData.push_back(metaData[i]);
		}
	}

	void balance() {
		vector<MetaData> newMetaData;
		for (int i = 0; i + 1 < (int)metaData.size(); i++) {
			int p1 = metaData[i].index;
			int p2 = metaData[i + 1].index;
			if ((int)Data[p1].size() + (int)Data[p2].size() < 2 * S) {
				newMetaData.clear();
				for (int j = 0; j < i; j++) newMetaData.push_back(metaData[j]);
				unpack(p1);
				unpack(p2);
				for (auto& x : Data[p2]) {
					Data[p1].push_back(x);
				}
				newMetaData.push_back({ p1, (int)Data[p1].size() });
				Data[p2].clear();
				for (int j = i + 2; j < (int)metaData.size(); j++) newMetaData.push_back(metaData[j]);
				metaData = newMetaData;
				balance();
				return;
			}
		}
	}

	void ins(int k, int e) {
		vector<MetaData> newMetaData;
		k--;
		if (k == 0) {
			newMetaData.clear();
			vector<int> v = { e };
			int p = placeData(v);
			newMetaData.push_back({ p, 1 });
			for (int j = 0; j < (int)metaData.size(); j++) newMetaData.push_back(metaData[j]);
			metaData = newMetaData;
		}
		else {
			newMetaData.clear();
			split(k - 1);
			vector<int> v = { e };

			int Until = -1;
			{
				int sum = 0;
				for (int i = 0; i < (int)metaData.size(); i++) {
					sum += (int)Data[metaData[i].index].size();
					if (sum == k) {
						Until = i;
						break;
					}
				}
			}


			int p = placeData(v);
			for (int j = 0; j <= Until; j++) newMetaData.push_back(metaData[j]);
			newMetaData.push_back({ p, 1 });

			for (int j = Until + 1; j < (int)metaData.size(); j++) newMetaData.push_back(metaData[j]);
			metaData = newMetaData;
		}

		sz++;
		balance();
	}

	int get(int p) {
		p--;
		int sum = 0;
		for (int i = 0; i < (int)metaData.size(); i++) {
			if (p <= sum + metaData[i].len - 1) {
				unpack(metaData[i].index);
				return Data[metaData[i].index][p - sum];
			}
			sum += metaData[i].len;
		}
	}

	void print() {
		for (int i = 0; i < (int)metaData.size(); i++) {
			int p = metaData[i].index;
			if (!rev[p]) {
				for (int j = 0; j < (int)metaData[i].len; j++) {
					cout << Data[p][j] << " ";
				}
			}
			else {
				for (int j = (int)metaData[i].len - 1; j >= 0; j--) {
					cout << Data[p][j] << " ";
				}
			}
		}
		cout << "\n";
	}

	void del(int l, int r) {
		l--;
		r--;
		if (l >= 1) {
			split(l - 1);
		}
		split(r);
		int pr = -1;
		{
			int sum = 0;
			for (int i = 0; i < (int)metaData.size(); i++) {
				if (r == sum + metaData[i].len - 1) {
					pr = i;
					break;
				}
				sum += metaData[i].len;
			}
		}
		int pl = -1;
		if (l > 0) {
			int sum = 0;
			for (int i = 0; i < (int)metaData.size(); i++) {
				if (l - 1 == sum + metaData[i].len - 1) {
					pl = i;
					break;
				}
				sum += metaData[i].len;
			}
		}
		pl++;
		sz -= (r - l + 1);
		vector<MetaData> newMetaData;
		for (int j = 0; j < pl; j++) newMetaData.push_back(metaData[j]);
		for (int j = pl; j <= pr; j++) {
			int p = metaData[j].index;
			Data[p].clear();
		}
		for (int j = pr + 1; j < (int)metaData.size(); j++) newMetaData.push_back(metaData[j]);
		metaData = newMetaData;
		balance();
		return;
	}



	void rv(int l, int r) {
		l--;
		r--;
		if (l >= 1) {
			split(l - 1);
		}
		split(r);
		// find where r is
		int pr = -1;
		{
			int sum = 0;
			for (int i = 0; i < (int)metaData.size(); i++) {
				if (r == sum + metaData[i].len - 1) {
					pr = i;
					break;
				}
				sum += metaData[i].len;
			}
		}
		int pl = -1;
		if (l > 0) {
			int sum = 0;
			for (int i = 0; i < (int)metaData.size(); i++) {
				if (l - 1 == sum + metaData[i].len - 1) {
					pl = i;
					break;
				}
				sum += metaData[i].len;
			}
		}
		pl++;
		vector<MetaData> newMetaData;
		for (int j = 0; j < pl; j++) newMetaData.push_back(metaData[j]);
		for (int j = pr; j >= pl; j--) {
			newMetaData.push_back(metaData[j]);
			rev[metaData[j].index] = !rev[metaData[j].index];
		}
		for (int j = pr + 1; j < (int)metaData.size(); j++) newMetaData.push_back(metaData[j]);
		metaData = newMetaData;
		balance();
		return;
	}
};

signed main() {
#ifdef INFOARENA
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	freopen("secv8.in", "r", stdin);
	freopen("secv8.out", "w", stdout);
#else
	FILE* stream;
	freopen_s(&stream, "input.txt", "r", stdin);
#endif

	Smart sm;

	int q, _;
	cin >> q >> _;
	for (int iq = 1; iq <= q; iq++) {
		string s;
		cin >> s;
		if (s == "I") {
			int k, e;
			cin >> k >> e;
			sm.ins(k, e);
			continue;
		}
		if (s == "A") {
			int k;
			cin >> k;
			cout << sm.get(k) << "\n";
			continue;
		}
		if (s == "R") {
			int l, r;
			cin >> l >> r;
			sm.rv(l, r);
			continue;
		}
		if (s == "D") {
			int l, r;
			cin >> l >> r;
			sm.del(l, r);
			continue;
		}
	}
	sm.print();

	return 0;
}