Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Author : quickn (quickn.ga)
- Email : quickwshell@gmail.com
- */
- use std::str;
- use std::io::{self, BufWriter, Write};
- /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
- /// **REQUIRES** Rust 1.34 or higher
- pub struct UnsafeScanner<R> {
- reader: R,
- buf_str: Vec<u8>,
- buf_iter: str::SplitAsciiWhitespace<'static>,
- }
- impl<R: io::BufRead> UnsafeScanner<R> {
- pub fn new(reader: R) -> Self {
- Self {
- reader,
- buf_str: Vec::new(),
- buf_iter: "".split_ascii_whitespace(),
- }
- }
- /// This function should be marked unsafe, but noone has time for that in a
- /// programming contest. Use at your own risk!
- pub fn token<T: str::FromStr>(&mut self) -> T {
- loop {
- if let Some(token) = self.buf_iter.next() {
- return token.parse().ok().expect("Failed parse");
- }
- self.buf_str.clear();
- self.reader
- .read_until(b'\n', &mut self.buf_str)
- .expect("Failed read");
- self.buf_iter = unsafe {
- let slice = str::from_utf8_unchecked(&self.buf_str);
- std::mem::transmute(slice.split_ascii_whitespace())
- }
- }
- }
- }
- use std::fmt;
- use std::cmp::Ordering;
- use std::ops::{Add, Mul, Sub};
- use std::mem::MaybeUninit;
- use std::collections::HashMap;
- // Little-Endian U256
- #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
- struct U256 {
- vector: [u64;4]
- }
- impl U256 {
- fn new(vector: [u64;4]) -> Self {
- Self {
- vector
- }
- }
- fn from_u64(x: u64) -> Self {
- let mut data: [u64;4] = [0;4];
- data[0] = x;
- Self {
- vector: data
- }
- }
- }
- impl Add for U256 {
- type Output = U256;
- fn add(self, other: Self) -> Self {
- let mut data: [u64;4] = [0;4];
- let mut ceil = 0;
- for i in 0..4 {
- let mut res = ceil;
- res += self.vector[i] as u128;
- res += other.vector[i] as u128;
- ceil = res >> 64;
- data[i] = res as u64;
- }
- //assert_eq!(ceil, 0);
- Self {
- vector: data,
- }
- }
- }
- impl Sub for U256 {
- type Output = U256;
- fn sub(self, other: Self) -> Self {
- let mut data: [u64;4] = self.vector;
- let mut data2: [u64;4] = other.vector;
- for i in 0..data2.len() {
- data2[i] = !data2[i];
- }
- let mut ceil = 0;
- for i in 0..4 {
- let mut res = ceil;
- res += data2[i] as u128;
- if i == 0 {
- res += 1;
- }
- ceil = res >> 64;
- //dbg!((res, ceil));
- data2[i] = res as u64;
- }
- ceil = 0;
- for i in 0..4 {
- let mut res = ceil;
- res += data[i] as u128;
- res += data2[i] as u128;
- ceil = res >> 64;
- //dbg!((data[i], data2[i]));
- data[i] = res as u64;
- }
- //assert_eq!(ceil, 0);
- Self {
- vector: data,
- }
- }
- }
- impl Mul for U256 {
- type Output = Self;
- fn mul(self, other: Self) -> Self {
- let mut data: [u64;4] = [0;4];
- let mut ceil = 0;
- for i in 0..4 {
- let mut res = ceil;
- for j in 0..=i {
- res += (self.vector[j] as u128)*(other.vector[i-j] as u128);
- }
- ceil = res >> 64;
- data[i] = res as u64;
- }
- //assert_eq!(ceil, 0);
- Self {
- vector: data
- }
- }
- }
- impl PartialOrd for U256 {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- if self.vector[3] == other.vector[3] {
- if self.vector[2] == other.vector[2] {
- if self.vector[1] == other.vector[1] {
- if self.vector[0] == other.vector[0] {
- Some(Ordering::Equal)
- } else {
- Some(self.vector[0].cmp(&other.vector[0]))
- }
- } else {
- Some(self.vector[1].cmp(&other.vector[1]))
- }
- } else {
- Some(self.vector[2].cmp(&other.vector[2]))
- }
- } else {
- Some(self.vector[3].cmp(&other.vector[3]))
- }
- }
- }
- impl Ord for U256 {
- fn cmp(&self, other: &Self) -> Ordering {
- if self.vector[3] == other.vector[3] {
- if self.vector[2] == other.vector[2] {
- if self.vector[1] == other.vector[1] {
- if self.vector[0] == other.vector[0] {
- Ordering::Equal
- } else {
- self.vector[0].cmp(&other.vector[0])
- }
- } else {
- self.vector[1].cmp(&other.vector[1])
- }
- } else {
- self.vector[2].cmp(&other.vector[2])
- }
- } else {
- self.vector[3].cmp(&other.vector[3])
- }
- }
- }
- impl fmt::Display for U256 {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut input = format!("{:b}{:064b}{:064b}{:064b}",self.vector[3],self.vector[2],self.vector[1],self.vector[0]);
- let mut input_chars: Vec<char> = input.chars().collect();
- while input_chars.len() > 1 && input_chars.first().unwrap() == &'0' {
- input_chars.remove(0);
- }
- let mut n = input_chars.len();
- let mut input2: Vec<u8> = vec![0];
- for i in 0..n {
- input2.push(0);
- if input2[0] >= 5 { input2[0] += 3; }
- input2[0] <<= 1;
- input2[0] |= (input_chars[0] as u8) - ('0' as u8);
- input_chars.remove(0);
- let mut ceil = input2[0]>>4;
- if ceil >= 1 {
- input2[0] -= ceil<<4;
- }
- for j in 1..input2.len() {
- if input2[j] >= 5 { input2[j] += 3; }
- input2[j] <<= 1;
- input2[j] |= ceil;
- ceil = input2[j]>>4;
- if ceil >= 1 {
- input2[j] -= ceil<<4;
- }
- }
- }
- while input2.len() > 1 && input2.last().unwrap() == &0 {
- input2.remove(input2.len()-1);
- }
- Ok(for i in 0..input2.len() {
- write!(f, "{}", input2[input2.len()-1-i])?
- })
- }
- }
- fn main() {
- let (stdin, stdout) = (io::stdin(), io::stdout());
- let (mut scan, mut sout) = (UnsafeScanner::new(stdin.lock()), BufWriter::new(stdout.lock()));
- let (k, n): (U256, usize) = (U256::from_u64(scan.token::<u64>()), scan.token());
- let mut dfs = unsafe { MaybeUninit::zeroed().assume_init() };
- let dfs_rec = &mut dfs as *mut dyn FnMut((U256, U256, U256), u8, u8);
- let init_sol: (U256, U256, U256) = (U256::from_u64(0), U256::from_u64(1), k);
- let mut res = vec![];
- dfs = |(a, b, c): (U256, U256, U256), prev_visit: u8, depth: u8| {
- if depth < 13 {
- if k*(b+c) >= a && prev_visit != 1 {
- unsafe { (*dfs_rec)((k*(b+c)-a, b, c), 1, depth+1) };
- }
- if k*(a+c) >= b && prev_visit != 2 {
- unsafe { (*dfs_rec)((a, k*(a+c)-b, c), 2, depth+1) };
- }
- if k*(a+b) >= c && prev_visit != 3 {
- unsafe { (*dfs_rec)((a, b, k*(a+b)-c), 3, depth+1) };
- }
- }
- res.push((a, b, c))
- };
- //println!("{}", U256::new([0,1,0,0])*U256::new([0,1,0,0]));
- dfs(init_sol, 0, 1);
- let mut cnt = 0;
- let mut i = 0;
- let mut hash: HashMap<U256, bool> = HashMap::new();
- while cnt < n {
- let (a, b, c) = res[i];
- if hash.get(&a).is_none()
- && hash.get(&b).is_none()
- && hash.get(&c).is_none()
- && format!("{}", a).len() <= 100
- && format!("{}", b).len() <= 100
- && format!("{}", c).len() <= 100 {
- //println!("{}", cnt);
- writeln!(sout, "{} {} {}", a, b, c).ok();
- //assert_eq!(a*a + b*b + c*c, k*(a*b + b*c + a*c)+U256::from_u64(1));
- hash.insert(a, true);
- hash.insert(b, true);
- hash.insert(c, true);
- cnt += 1;
- }
- i += 1;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement