Cod sursa(job #2752665)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 18 mai 2021 21:18:20
Problema Secv8 Scor 100
Compilator rs Status done
Runda Arhiva de probleme Marime 9.01 kb
#![allow(dead_code)]
#![allow(non_snake_case)]

use std::fs::File;
use std::io::{*};
use std::mem;

struct Rng{
  x: u32,
}

impl Rng{
  fn new(val :i32) -> Rng {
    return Rng{
      x: val as u32,
    };
  }
  fn rand(&mut self) -> u32{
    self.x ^= self.x << 13;
    self.x ^= self.x >> 17;
    self.x ^= self.x << 5;
    return self.x;
  }
}

#[derive(Debug)]
struct Node{
  val: i32,
  prio: u32,
  sz: usize,
  lazy: bool,
  left: Option<Box<Node>>,
  right: Option<Box<Node>>,
}

impl Node {
  fn new(_val: i32, _prio: u32) -> Node{
    return Node {
      val: _val,
      prio: _prio,
      sz: 1,
      lazy: false,
      left: None,
      right: None,
    };
  }
  
  fn refresh(&mut self) {
    if self.lazy == false {
      return ;
    }
    std::mem::swap(&mut self.left, &mut self.right);
    self.lazy = false;
    
    if let Some(x) = self.left.take() {
      let mut val = x;
      val.lazy = !val.lazy;
      self.left = Some(val);
    }
    
    if let Some(x) = self.right.take() {
      let mut val = x;
      val.lazy = !val.lazy;
      self.right = Some(val);
    }
  }

  fn computesize(&mut self) {
    self.sz = 1;
    self.sz += match &self.left {
      None => 0,
      Some(x) => x.sz,
    };
    self.sz += match &self.right {
      None => 0,
      Some(x) => x.sz,
    };
  }

  fn getsize(node : &Option<Box<Node>>) -> usize {
    match node {
      None => 0,
      Some(x) => x.sz,
    }
  }

  fn flip(self) -> Node{
    let mut newtreap = self;
    newtreap.lazy ^= true;
    return newtreap;
  }
  
  fn split_treap(node : Option<Box<Node>>, val: usize ) -> (Option<Box<Node>>, Option<Box<Node>>) {
    match node {
      None => return (None, None),
      _ => (),
    };
    let mut node = node.unwrap();
    node.refresh();
    node.computesize();
    let sz_left = Node::getsize(&node.left);
    
    if sz_left < val {
      let pair = Node::split_treap(node.right, val - sz_left - 1);
      node.right = pair.0;
      node.refresh();
      node.computesize();
      return (Some(node), pair.1);
    } else {
      let pair = Node::split_treap(node.left, val);
      node.left = pair.1;
      node.refresh();
      node.computesize();
      return (pair.0, Some(node));
    }
  }
  
  fn split_treap2(node : Option<Box<Node>>, val: i32 ) -> (Option<Box<Node>>, Option<Box<Node>>) {
    match node {
      None => return (None, None),
      _ => (),
    };
    let mut node = node.unwrap();
    node.refresh();
    node.computesize();
    if node.val < val {
      let pair = Node::split_treap2(node.right, val);
      node.right = pair.0;
      node.refresh();
      node.computesize();
      return (Some(node), pair.1);
    } else {
      let pair = Node::split_treap2(node.left, val);
      node.left = pair.1;
      node.refresh();
      node.computesize();
      return (pair.0, Some(node));
    }
  }

  fn join_treap(left: Option<Box<Node>>, right: Option<Box<Node>>) -> Option<Box<Node>> {
    if let None = left {
      if let None = right {
        return None;
      } else {
        return right;
      }
    } else if let None = right {
      return left;
    } else {
      let mut left = left.unwrap();
      let mut right = right.unwrap();
      left.refresh();
      right.refresh();

      if left.prio < right.prio {
        right.left = Node::join_treap(Some(left), right.left);
        right.computesize();
        right.refresh();
        return Some(right);
      } else {
        left.right = Node::join_treap(left.right, Some(right));
        left.computesize();
        left.refresh();
        return Some(left);
      }
    }
  }

  fn insert(node: Option<Box<Node>>, pos :usize, val: i32, prio :u32) -> Option<Box<Node>> {
    if let None = node {
      return Some(Box::new(Node::new(val, prio)));
    } else {
      let mut node = node.unwrap();
      node.refresh();
      node.computesize();
      
      let left_size = Node::getsize(&node.left);
      if node.prio < prio {
        let pair = Node::split_treap(Some(node), pos - 1);
        let mut newroot = Box::new(Node::new(val, prio));
        newroot.left = pair.0;
        newroot.right = pair.1;
        
        newroot.computesize();
        newroot.refresh();
        return Some(newroot);
      } else {
        if pos <= left_size + 1 {
          node.left = Node::insert(node.left, pos, val, prio);
        } else {
          node.right = Node::insert(node.right, pos - left_size - 1, val, prio);
        }

        node.computesize();
        node.refresh();
        return Some(node);
      }
    }
  }

  fn erase(node: Option<Box<Node>>, val: i32) -> Option<Box<Node>> {
    if let None = node {
      return None;
    } else {
      let mut node = node.unwrap();
      node.refresh();
      node.computesize();
      if node.val == val {
        return Node::join_treap(node.left, node.right);
      } else if(val < node.val) {
        node.left = Node::erase(node.left, val);
        node.refresh();
        node.computesize();
        return Some(node);
      } else {
        node.right = Node::erase(node.right, val);
        node.refresh();
        node.computesize();
        return Some(node);
      }
    }
  }

  fn find(node: Option<Box<Node>>, pos : usize) -> (Option<i32>, Option<Box<Node>>) {
    if let None = node {
      return (None, node);
    } else {
      let mut node = node.unwrap();
      node.refresh();
      node.computesize();
      let size_left = Node::getsize(&node.left);
      if size_left + 1 < pos {
        let pair = Node::find(node.right, pos - size_left - 1);
        node.right = pair.1;
        return (pair.0, Some(node));
      } else if size_left + 1 == pos {
        return (Some(node.val), Some(node));
      } else { 
        let pair = Node::find(node.left, pos);
        node.left = pair.1;
        return (pair.0, Some(node));
      }
    }
  }

  fn collect(node: Option<Box<Node>>, sol_vector: &mut Vec<i32>, prop: bool) {
    if let None = node {
      return ;
    } else {
      let node = node.unwrap();
      let prop = prop ^ node.lazy;
      if prop == false {
        Node::collect(node.left, sol_vector, prop);
        sol_vector.push(node.val);
        Node::collect(node.right, sol_vector, prop);
      } else {
        Node::collect(node.right, sol_vector, prop);
        sol_vector.push(node.val);
        Node::collect(node.left, sol_vector, prop);
      }
    }
  }
}

#[derive(Debug)]
struct Treap{
  root: Option<Box<Node>>,
}

impl Treap {
  fn new() -> Treap {
    return Treap {
      root: None,
    };
  }

  fn insert(&mut self, pos :usize, val :i32, prio: u32) {
    self.root = Node::insert(self.root.take(), pos, val, prio)
  }

  fn reverse(&mut self, start :usize, stop :usize) {
    let mut pair = Node::split_treap(self.root.take(), stop);
    let mut pair2 = Node::split_treap(pair.0, start - 1);
    pair2.1 = Some(Box::new(pair2.1.unwrap().flip()));
    self.root = Node::join_treap(Node::join_treap(pair2.0, pair2.1), pair.1);
  }

  fn access(&mut self, pos : usize) -> i32{
    let pair = Node::find(self.root.take(), pos);
    self.root = pair.1;
    return pair.0.unwrap();
  }

  fn mass_erase(&mut self, start: usize, stop :usize) {
    let mut pair = Node::split_treap(self.root.take(), stop);
    let mut pair2 = Node::split_treap(pair.0, start - 1);
    self.root = Node::join_treap(pair2.0, pair.1);
  }

  fn collect(treap :Treap, sol_vector: &mut Vec<i32>) {
    Node::collect(treap.root, sol_vector, false);
  }
}

fn main() {
  let mut input = BufReader::new(File::open("secv8.in").unwrap());	
  let mut output = BufWriter::new(File::create("secv8.out").unwrap());
  let mut line = String::new();
  input.read_line(&mut line).expect("Failed to read line");
  let args: Vec<i32> = line.trim().split(' ')
                       .map(|x| x.parse().expect("Expected integer"))
                       .collect();
  let n = args[0];
  let mut treap = Treap::new();
  let mut myRng = Rng::new(69);

  for _i in 0..n {
    let mut line = String::new();
    input.read_line(&mut line).expect("Failed to read line");
    let args: Vec<&str> = line.trim().split(' ').collect();
    
    let first_arg : Vec<char> = args[0].chars().collect();

    match first_arg[0] {
      'I' => {
        let pos : usize;
        let val : i32;
        pos = args[1].parse().unwrap();
        val = args[2].parse().unwrap();
        treap.insert(pos, val, myRng.rand());
        ()
      }
      'A' => {
        let pos: usize;
        pos = args[1].parse().unwrap();
        let val = Treap::access(&mut treap, pos);
        writeln!(output, "{}", val).expect("failed to write");
        () 
      },
      'R' => {
        let start: usize;
        let stop: usize;
        start = args[1].parse().unwrap();
        stop = args[2].parse().unwrap();
        treap.reverse(start, stop);
        ()
      }
      'D' => {
        let start: usize;
        let stop: usize;
        start = args[1].parse().unwrap();
        stop = args[2].parse().unwrap();
        treap.mass_erase(start, stop);
        ()
      }
      _ => () ,
    }
  }

  let mut sol : Vec<i32> = Vec::new();
  Treap::collect(treap, &mut sol);
  for it in sol {
    write!(output, "{} ", it).expect("failed to write");
  }
}