use std::mem::swap;
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Write};
struct MyRng {
a: i64,
b: i64,
c: i64,
}
const MOD: i64 = 1000000007;
impl MyRng {
fn new(seed: i32) -> MyRng {
MyRng {
a: seed as i64,
b: 1,
c: seed as i64,
}
}
fn get_rng(&mut self) -> i32 {
self.c = (self.c * self.a + self.b) % MOD;
self.c as i32
}
}
#[derive(Debug)]
struct Treap {
key: i32,
prio: i32,
size: usize,
left: Option<Box<Treap>>,
right: Option<Box<Treap>>,
rev: bool,
}
impl Treap {
fn new(key: i32, prio: i32) -> Treap {
Treap {
key,
prio,
size: 696969,
left: None,
right: None,
rev: false,
}
}
fn refresh(&mut self) {
self.size = 1;
if let Some(mut x) = self.left.take() {
if self.rev {
x.rev ^= true;
}
self.size += x.size;
self.left = Some(x);
}
if let Some(mut x) = self.right.take() {
if self.rev {
x.rev ^= true;
}
self.size += x.size;
self.right = Some(x);
}
if self.rev {
swap(&mut self.left, &mut self.right);
self.rev = false;
}
}
fn get_size(x: Option<Box<Treap>>) -> (usize, Option<Box<Treap>>){
if let Some(t) = x {
(t.size, Some(t))
} else {
(0, None)
}
}
fn join(a: Option<Box<Treap>>, b: Option<Box<Treap>>) -> Option<Box<Treap>> {
if let None = a { return b; }
if let None = b { return a; }
let (mut a, mut b) = (a.unwrap(), b.unwrap());
a.refresh();
b.refresh();
if a.prio < b.prio {
let (left, right) = (a.left.take(), a.right.take());
a.right = Treap::join(right, Some(b));
a.left = left;
a.refresh();
Some(a)
} else {
let (left, right) = (b.left.take(), b.right.take());
b.left = Treap::join(Some(a), left);
b.right = right;
b.refresh();
Some(b)
}
}
fn split(t: Option<Box<Treap>>, val: usize) -> (Option<Box<Treap>>, Option<Box<Treap>>) {
if let None = t { return (None, None); }
let mut t = t.unwrap();
t.refresh();
let (left, right) = (t.left.take(), t.right.take());
let (leftsize, left) = Treap::get_size(left);
if leftsize + 1 <= val {
let (lsplit, rsplit) = Treap::split(right, val - leftsize - 1);
t.right = lsplit;
t.left = left;
t.refresh();
(Some(t), rsplit)
} else {
let (lsplit, rsplit) = Treap::split(left, val);
t.left = rsplit;
t.right = right;
t.refresh();
(lsplit, Some(t))
}
}
fn add(t: Option<Box<Treap>>, k: usize, val: i32, prio: i32) -> Option<Box<Treap>> {
let (left, right) = Treap::split(t, k - 1);
let newnode = Some(Box::new(Treap::new(val, prio)));
Treap::join(Treap::join(left, newnode), right)
}
fn delete(t: Option<Box<Treap>>, l: usize, r: usize) -> Option<Box<Treap>> {
let (left, right) = Treap::split(t, r);
let (left, _mid) = Treap::split(left, l - 1);
Treap::join(left, right)
}
fn access(t: Option<Box<Treap>>, k: usize) -> (Option<Box<Treap>>, i32) {
let (left, right) = Treap::split(t, k);
let (left, mid) = Treap::split(left, k - 1);
let mid = mid.unwrap();
let res = mid.key;
(Treap::join(Treap::join(left, Some(mid)), right), res)
}
fn reverse(t: Option<Box<Treap>>, l: usize, r: usize) -> Option<Box<Treap>> {
let (left, right) = Treap::split(t, r);
let (left, mid) = Treap::split(left, l - 1);
let mut mid = mid.unwrap();
mid.rev ^= true;
Treap::join(Treap::join(left, Some(mid)), right)
}
fn collect(t: Option<Box<Treap>>, mut collection: Vec<i32>) -> Vec<i32> {
match t {
None => { collection }
Some(mut t) => {
t.refresh();
let (left, right) = (t.left.take(), t.right.take());
collection = Treap::collect(left, collection);
collection.push(t.key);
collection = Treap::collect(right, collection);
collection
}
}
}
}
fn main() {
let mut treap: Option<Box<Treap>> = None;
let mut rng = MyRng::new(269696969);
let mut fin = BufReader::new(File::open("secv8.in").unwrap());
let mut fout = BufWriter::new(File::create("secv8.out").unwrap());
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let args: Vec<&str> = line.trim().split(' ').collect();
assert_eq!(args.len(), 2);
let n: usize = args[0].parse().unwrap();
for _ in 0..n {
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let args: Vec<&str> = line.trim().split(' ').collect();
assert!(args.len() > 0);
match args[0] {
"I" => {
assert_eq!(args.len(), 3);
let (k, e): (usize, i32) = (args[1].parse().unwrap(),
args[2].parse().unwrap());
treap = Treap::add(treap, k, e, rng.get_rng());
}
"R" => {
assert_eq!(args.len(), 3);
let (l, r): (usize, usize) = (args[1].parse().unwrap(),
args[2].parse().unwrap());
treap = Treap::reverse(treap, l, r);
}
"A" => {
assert_eq!(args.len(), 2);
let k: usize = args[1].parse().unwrap();
let (treapres, res) = Treap::access(treap, k);
fout.write(format!("{}\n", res).as_bytes()).unwrap();
treap = treapres;
}
"D" => {
assert_eq!(args.len(), 3);
let (l, r): (usize, usize) = (args[1].parse().unwrap(),
args[2].parse().unwrap());
treap = Treap::delete(treap, l, r);
}
_ => {}
}
}
Treap::collect(treap, Vec::new()).iter().for_each(|x| { fout.write(format!("{} ", x).as_bytes()).unwrap(); });
fout.flush().unwrap();
}