Cod sursa(job #2640577)

Utilizator TincaMateiTinca Matei TincaMatei Data 6 august 2020 22:28:34
Problema Secv8 Scor 0
Compilator rs Status done
Runda Arhiva de probleme Marime 5.41 kb
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: 1,
      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 joined = Treap::join(a.right, Some(b));
      a.right = joined;
      a.refresh();
      Some(a)
    } else {
      let joined = Treap::join(Some(a), b.left);
      b.left = joined;
      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 mut res = Treap::collect(t.left, collection);
      res.push(t.key);
      collection = Treap::collect(t.right, res);
      collection
    }
    }
  }
}

fn main() {
  let mut treap: Option<Box<Treap>> = None;
  let mut rng = MyRng::new(696969);

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