Pagini recente » Cod sursa (job #617926) | Cod sursa (job #488249) | Cod sursa (job #2834976) | Cod sursa (job #2369856) | Cod sursa (job #3253852)
// Author: Tanasescu Andrei-Rares
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <iomanip>
#include <vector>
#include <cassert>
#include <random>
#include <ctime>
#pragma GCC optimize("O3")
#define fi first
#define se second
#define pb push_back
#define pf push_front
using namespace std;
ifstream fin ("secv8.in");
ofstream fout ("secv8.out");
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const ll Nmax=1e6+5, inf=1e9+5;
mt19937 mt(time(0));
struct NODE{
int x, y, sz;
bool rev;
NODE* left, *right;
NODE(int val){
x=val;
y=mt();
sz=1;
rev=0;
left=right=nullptr;
}
};
// marimea subarborelui
inline int get_sz(NODE* node){
if (node==nullptr)
return 0;
return node->sz;
}
// indicele pe care il are in subarbore
inline int get_ind(NODE* node){
assert(node!=nullptr);
return get_sz(node->left)+1;
}
// recalculam parametrii nodului
inline void upd_node(NODE* node){
assert(node!=nullptr);
node->sz=get_sz(node->left)+1+get_sz(node->right);
}
inline void push_lazy(NODE* node){
assert(node!=nullptr);
if (node->rev){
node->rev=0;
if (node->left!=nullptr)
node->left->rev^=1;
if (node->right!=nullptr)
node->right->rev^=1;
swap(node->left, node->right);
}
}
// split pana la pos
pair<NODE*, NODE*> split(NODE* treap, int pos){
if (treap==nullptr)
return {nullptr, nullptr};
push_lazy(treap);
int ind=get_ind(treap);
if (ind<=pos){
auto rs=split(treap->right, pos-ind);
treap->right=rs.fi;
upd_node(treap);
return {treap, rs.se};
}
else{
auto ls=split(treap->left, pos);
treap->left=ls.se;
upd_node(treap);
return {ls.fi, treap};
}
}
// merge, y-ul mai mare e dominant
NODE* merge(NODE* ltreap, NODE* rtreap){
if (ltreap==nullptr && rtreap==nullptr)
return nullptr;
if (ltreap==nullptr)
return rtreap;
if (rtreap==nullptr)
return ltreap;
push_lazy(ltreap);
push_lazy(rtreap);
if (ltreap->y>rtreap->y){
ltreap->right=merge(ltreap->right, rtreap);
upd_node(ltreap);
return ltreap;
}
else{
rtreap->left=merge(ltreap, rtreap->left);
upd_node(rtreap);
return rtreap;
}
}
inline NODE* insert(NODE* treap, int pos, int val){
auto p1_2=split(treap, pos-1);
NODE* new_treap= new NODE(val);
return merge(p1_2.fi, merge(new_treap, p1_2.se));
}
inline NODE* erase(NODE* treap, int l, int r){
auto p1_23=split(treap, l-1);
auto p2_3=split(p1_23.se, r-l+1
);
return merge(p1_23.fi, p2_3.se);
}
inline NODE* reverse(NODE* treap, int l, int r){
auto p1_23=split(treap, l-1);
auto p2_3=split(p1_23.se, r-l+1);
p2_3.fi->rev^=1;
return merge(p1_23.fi, merge(p2_3.fi, p2_3.se));
}
int acces(NODE* treap, int pos){
assert(treap!=nullptr);
push_lazy(treap);
int ind=get_ind(treap);
if (ind==pos)
return treap->x;
if (ind<pos)
return acces(treap->right, pos-ind);
else return acces(treap->left, pos);
}
void afis(NODE* treap){
if (treap==nullptr)
return;
push_lazy(treap);
afis(treap->left);
fout<<treap->x<<' ';
afis(treap->right);
}
NODE* treap=nullptr;
int n;
bool Erev;
int main()
{
fin>>n>>Erev;
char t; int a, b;
for (int i=0; i<n; i++){
fin>>t;
if (t=='I'){
fin>>a>>b;
treap=insert(treap, a, b);
}
else if (t=='A'){
fin>>a;
fout<<acces(treap, a)<<'\n';
}
else if (t=='R'){
fin>>a>>b;
treap=reverse(treap, a, b);
}
else{
fin>>a>>b;
treap=erase(treap, a, b);
}
/*afis(treap);
fout<<'\n';*/
}
afis(treap);
return 0;
}