Pagini recente » Cod sursa (job #2144147) | Cod sursa (job #228419) | Cod sursa (job #2037018) | Cod sursa (job #2926532) | Cod sursa (job #3228738)
use std::{
fs::File,
io::{BufRead, BufReader, BufWriter, Write},
};
#[derive(Debug, Clone)]
struct LinkedListNode<T> {
element: T,
next: *mut LinkedListNode<T>,
}
impl<T> LinkedListNode<T> {
fn new(element: T) -> Self {
Self {
element,
next: std::ptr::null_mut(),
}
}
}
#[derive(Debug, Clone)]
struct LinkedList<T> {
head: *mut LinkedListNode<T>,
}
impl<T> LinkedList<T> {
fn new() -> Self {
Self {
head: std::ptr::null_mut(),
}
}
}
impl<T> LinkedList<T> {
fn drain(&mut self) -> Self {
let p = self.head;
self.head = std::ptr::null_mut();
Self {
head: p,
}
}
fn is_empty(&self) -> bool {
self.head.is_null()
}
fn pop(&mut self) -> *mut LinkedListNode<T> {
if self.is_empty() {
return std::ptr::null_mut();
}
let next = unsafe {
(*self.head).next
};
let to_return = self.head;
self.head = next;
unsafe {
(*to_return).next = std::ptr::null_mut();
};
to_return
}
fn push(&mut self, element: T) {
let new_node = Box::new(LinkedListNode::new(element));
let new_node = Box::into_raw(new_node);
if self.is_empty() {
self.head = new_node;
} else {
unsafe {
(*new_node).next = self.head;
};
self.head = new_node;
}
}
}
#[derive(Debug, Clone)]
struct PairingHeap {
top: Option<u32>,
sub_heaps: LinkedList<PairingHeap>,
}
impl PairingHeap {
fn drain(&mut self) -> Self {
Self {
top: self.top.take(),
sub_heaps: self.sub_heaps.drain(),
}
}
fn is_empty(&self) -> bool {
self.top.is_none() && self.sub_heaps.is_empty()
}
fn max(&mut self) -> Option<u32> {
let val = self.top.take();
let mut sub_heaps = self.sub_heaps.drain();
while !sub_heaps.is_empty() {
let child = sub_heaps.pop();
if !child.is_null() {
let mut child = unsafe {Box::from_raw(child)};
self.meld( &mut (child.element));
}
}
val
}
fn meld(&mut self, other: &mut PairingHeap) {
if other.is_empty() {
return;
}
if self.is_empty() {
self.top = other.top;
self.sub_heaps = other.sub_heaps.drain();
return;
}
if self.top.unwrap() >= other.top.unwrap() {
self.sub_heaps.push(other.drain());
} else {
let old_top = self.top.take();
let old_sub_heaps = self.sub_heaps.drain();
let old_self = PairingHeap {
top: old_top,
sub_heaps: old_sub_heaps,
};
self.top = other.top.take();
self.sub_heaps = other.sub_heaps.drain();
self.sub_heaps.push(old_self);
}
}
fn insert(&mut self, element: u32) {
let mut other = PairingHeap {
top: Some(element),
sub_heaps: LinkedList::new(),
};
self.meld(&mut other);
}
}
fn main() {
let mut input_file = BufReader::new(File::open("mergeheap.in").unwrap());
let mut current_line = String::new();
let _ = input_file.read_line(&mut current_line).unwrap();
let (n, q) = current_line.trim().split_once(' ').unwrap();
let n = n.parse::<u32>().unwrap();
let q = q.parse::<u32>().unwrap();
let mut ph: Vec<PairingHeap> = vec![
PairingHeap {
top: None,
sub_heaps: LinkedList::new()
};
n as usize
];
let mut out_file = BufWriter::new(File::create("mergeheap.out").unwrap());
for _ in 0..q {
current_line.clear();
let _ = input_file.read_line(&mut current_line).unwrap();
let (op, rest) = current_line.trim().split_once(' ').unwrap();
match op {
"1" => {
let (m, x) = rest.split_once(' ').unwrap();
let m = m.parse::<usize>().unwrap();
let x = x.parse::<u32>().unwrap();
ph[m - 1].insert(x);
}
"2" => {
let m = rest.parse::<usize>().unwrap();
let val = ph[m - 1].max().unwrap();
let _ = writeln!(out_file, "{val}").unwrap();
}
"3" => {
let (a, b) = rest.split_once(' ').unwrap();
let a = a.parse::<usize>().unwrap();
let b = b.parse::<usize>().unwrap();
// Can't do two mutable borrows at the same time from a vector :sadcat:
if a < b {
let (aa, bb) = ph.split_at_mut(b - 1);
aa[a - 1].meld(&mut bb[0]);
} else if a > b {
let (aa, bb) = ph.split_at_mut(a - 1);
bb[0].meld(&mut aa[b - 1]);
} else {
// WAT
}
}
_ => panic!("Unknown op {op}"),
}
}
}