結果
| 問題 |
No.381 名声値を稼ごう Extra
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-04-19 19:55:28 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 27,788 bytes |
| コンパイル時間 | 17,951 ms |
| コンパイル使用メモリ | 390,104 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-09-22 13:46:27 |
| 合計ジャッジ時間 | 14,140 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 2 |
ソースコード
#![allow(non_snake_case, unused_imports)]
//////////////////////////////// LIBRARY START ////////////////////////////////
#[macro_use]
pub mod contest {
#[macro_use]
pub mod num {
pub use self::biguint::*;
pub use self::num::*;
#[macro_use]
pub mod num {
use std::cmp::PartialEq;
use std::ops::*;
pub trait NumOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
pub trait Num: Zero + One + RefNum<Self> + PartialEq<Self>
where
Self: Sized,
{
}
pub trait Zero {
fn zero() -> Self;
}
pub trait One {
fn one() -> Self;
}
macro_rules! impl_num {
( $t: ty, $zero: expr, $one: expr) => {
impl Zero for $t {
fn zero() -> $t {
$zero
}
}
impl One for $t {
fn one() -> $t {
$one
}
}
impl NumOps<$t, $t> for $t {}
impl<'r> NumOps<&'r $t, $t> for $t {}
impl RefNum<$t> for $t {}
impl Num for $t {}
};
}
impl_num!(i32, 0, 1);
impl_num!(i64, 0, 1);
impl_num!(f32, 0.0, 1.0);
impl_num!(f64, 0.0, 1.0);
#[cfg(test)]
mod test {
macro_rules! assert_op {
($left:ident $op:tt $right:ident == $expected:expr) => {
assert_eq!((&$left) $op (&$right), $expected);
assert_eq!((&$left) $op $right.clone(), $expected);
assert_eq!($left.clone() $op (&$right), $expected);
assert_eq!($left.clone() $op $right.clone(), $expected);
};
}
#[test]
fn test_it() {
let a = 3;
let b = 2;
assert_op!(a * b == 6);
assert_op!(a + b == 5);
}
}
}
#[macro_use]
pub mod algorithm {
pub fn add3(a: u32, b: u32, carry: bool) -> (u32, bool) {
let (x, c) = a.overflowing_add(b);
if !carry {
return (x, c);
}
let (x2, c2) = x.overflowing_add(1);
(x2, c || c2)
}
pub fn sub3(a: u32, b: u32, carry: bool) -> (u32, bool) {
let (x, c) = a.overflowing_sub(b);
if !carry {
return (x, c);
}
let (x2, c2) = x.overflowing_sub(1);
(x2, c || c2)
}
}
#[macro_use]
pub mod biguint {
use std;
use std::cmp::Ordering;
use std::ops::*;
use super::algorithm;
use super::{One, Zero};
#[derive(Clone, Debug, Hash)]
pub struct BigUint {
// [3, 2] represents 3 + (2 << 32).
data: Vec<u32>,
}
impl std::fmt::Display for BigUint {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.data.len() == 0 {
return write!(f, "0");
}
let base = 1_000_000_000u64;
// [3, 2] represents 3 + (2 * base).
let mut res = vec![];
for d in self.data.iter().rev() {
let mut carry = *d as u64;
for x in res.iter_mut() {
let v = (*x << 32) + carry;
*x = v % base;
carry = v / base;
}
while carry > 0 {
res.push(carry % base);
carry /= base;
}
}
debug_assert_ne!(res.last(), Some(&0));
let (rest, top) = res.split_at(res.len() - 1);
write!(f, "{}", top[0])?;
for x in rest.iter().rev() {
write!(f, "{:09}", x)?;
}
Ok(())
}
}
impl PartialEq for BigUint {
#[inline]
fn eq(&self, other: &BigUint) -> bool {
match self.cmp(other) {
Ordering::Equal => true,
_ => false,
}
}
}
impl Eq for BigUint {}
impl PartialOrd for BigUint {
#[inline]
fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for BigUint {
#[inline]
fn cmp(&self, other: &BigUint) -> Ordering {
cmp_slice(&self.data[..], &other.data[..])
}
}
fn cmp_slice(a: &[u32], b: &[u32]) -> Ordering {
debug_assert!(a.last() != Some(&0));
debug_assert!(b.last() != Some(&0));
if a.len() < b.len() {
return Ordering::Less;
} else if a.len() > b.len() {
return Ordering::Greater;
}
for i in (0..a.len()).rev() {
let c = a[i].cmp(&b[i]);
if c != Ordering::Equal {
return c;
}
}
Ordering::Equal
}
impl From<u64> for BigUint {
fn from(mut x: u64) -> BigUint {
let mut data = vec![];
while x > 0 {
data.push((x & u32::max_value() as u64) as u32);
x >>= 32;
}
BigUint { data: data }
}
}
#[derive(Debug, PartialEq)]
pub struct ParseBigUintError;
impl std::str::FromStr for BigUint {
type Err = ParseBigUintError;
fn from_str(s: &str) -> Result<BigUint, ParseBigUintError> {
let s = s.as_bytes();
if s.iter().any(|c| *c < b'0' || b'9' < *c) {
return Err(ParseBigUintError);
}
fn parse_u32(s: &[u8]) -> u32 {
s.iter().fold(0u32, |acc, c| acc * 10 + (*c - b'0') as u32)
}
let mut data = vec![];
let base = 1_000_000_000u64;
let chunk_size = 9;
let (head, tail) = s.split_at(s.len() % chunk_size);
if !head.is_empty() {
data.push(parse_u32(head));
}
debug_assert_eq!(tail.len() % chunk_size, 0);
for ch in tail.chunks(chunk_size) {
// data *= base
let mut carry = parse_u32(ch) as u64;
for d in data.iter_mut() {
let v = *d as u64 * base + carry;
*d = v as u32;
carry = v >> 32;
}
if carry > 0 {
data.push(carry as u32);
}
}
// For "0" etc.
while data.last() == Some(&0) {
data.pop();
}
debug_assert_ne!(data.last(), Some(&0));
Ok(BigUint { data: data })
}
}
impl Zero for BigUint {
fn zero() -> BigUint {
BigUint::from(0)
}
}
impl One for BigUint {
fn one() -> BigUint {
BigUint::from(1)
}
}
impl<'a, 'b> Add<&'b BigUint> for &'a BigUint {
type Output = BigUint;
fn add(self, other: &'b BigUint) -> BigUint {
let n = std::cmp::max(self.data.len(), other.data.len());
let mut data = vec![];
let mut carry = false;
for i in 0..n {
let a = self.data.get(i).map_or(0, |x| *x);
let b = other.data.get(i).map_or(0, |x| *x);
let (x, c) = algorithm::add3(a, b, carry);
carry = c;
data.push(x);
}
if carry {
data.push(1);
}
debug_assert_ne!(data.last(), Some(&0));
BigUint { data: data }
}
}
impl<'a, 'b> Sub<&'b BigUint> for &'a BigUint {
type Output = BigUint;
fn sub(self, other: &'b BigUint) -> BigUint {
debug_assert!(self >= other);
let n = std::cmp::max(self.data.len(), other.data.len());
let mut data = vec![];
let mut carry = false;
for i in 0..n {
let a = self.data.get(i).map_or(0, |x| *x);
let b = other.data.get(i).map_or(0, |x| *x);
let (x, c) = algorithm::sub3(a, b, carry);
carry = c;
data.push(x);
}
debug_assert!(!carry);
while data.last() == Some(&0) {
data.pop();
}
debug_assert_ne!(data.last(), Some(&0));
BigUint { data: data }
}
}
impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {
type Output = BigUint;
fn mul(self, other: &'b BigUint) -> BigUint {
if self == &BigUint::zero() || other == &BigUint::zero() {
return BigUint::zero();
}
let n = self.data.len() + other.data.len() - 1;
let mut data = vec![];
let mut carry = 0u64;
let u32max = u32::max_value() as u64;
for i in 0..n {
// 2 1 0 - self (j)
// 1 0 - other(k)
// ----------------
// 2,0 1,0 0,0
// 2,1 1,1 0,1
// | | | |
// 3 2 1 0 - i
let mut digit = carry & u32max;
carry >>= 32;
let from = if i + 1 >= other.data.len() {
i + 1 - other.data.len()
} else {
0
};
for j in from..std::cmp::min(i + 1, self.data.len()) {
let k = i - j;
let x = self.data[j] as u64;
let y = other.data[k] as u64;
let val = digit + x * y;
digit = val & u32max;
carry += val >> 32;
}
debug_assert!(digit <= u32max);
data.push(digit as u32);
}
if carry > 0 {
debug_assert!(carry <= u32max);
data.push(carry as u32);
}
debug_assert_ne!(data.last(), Some(&0));
BigUint { data: data }
}
}
macro_rules! impl_others {
($tr:tt $func: ident) => {
impl<'a> $tr<BigUint> for &'a BigUint {
type Output = BigUint;
fn $func(self, x: BigUint) -> BigUint {
self.$func(&x)
}
}
impl<'b> $tr<&'b BigUint> for BigUint {
type Output = BigUint;
fn $func(self, x: &'b BigUint) -> BigUint {
(&self).$func(x)
}
}
impl $tr<BigUint> for BigUint {
type Output = BigUint;
fn $func(self, x: BigUint) -> BigUint {
(&self).$func(&x)
}
}
};
}
impl_others!(Add add);
impl_others!(Sub sub);
impl_others!(Mul mul);
#[cfg(test)]
mod test {
use super::*;
macro_rules! assert_op {
($left:ident $op:tt $right:ident == $expected:expr) => {
assert_eq!((&$left) $op (&$right), $expected);
assert_eq!((&$left) $op $right.clone(), $expected);
assert_eq!($left.clone() $op (&$right), $expected);
assert_eq!($left.clone() $op $right.clone(), $expected);
};
}
#[test]
fn test_add() {
let a = BigUint::from(3);
let b = BigUint::from(2);
let c = BigUint::from(5);
assert_op!(a + b == c);
}
#[test]
fn test_add_zero() {
let a = BigUint::zero();
let b = BigUint::one();
assert_op!(a + a == a);
assert_op!(a + b == b);
assert_op!(b + a == b);
}
#[test]
fn test_add_big() {
let a = BigUint::from(3_000_000_000_000);
let b = BigUint::from(2_000_000_000_000);
let c = BigUint::from(5_000_000_000_000);
assert_op!(a + b == c);
}
#[test]
fn test_add_with_carry() {
use std;
let a = BigUint::from(std::u32::MAX as u64);
let b = BigUint::from(1);
let c = BigUint::from(std::u32::MAX as u64 + 1);
assert_op!(a + b == c);
}
#[test]
fn test_sub() {
let a = BigUint::from(3);
let b = BigUint::from(2);
let c = BigUint::from(5);
assert_op!(c - b == a);
}
#[test]
fn test_sub_zero() {
let a = BigUint::zero();
let b = BigUint::one();
assert_op!(b - a == b);
assert_op!(a - a == a);
}
#[test]
fn test_sub_big() {
let a = BigUint::from(3_000_000_000_000);
let b = BigUint::from(2_000_000_000_000);
let c = BigUint::from(5_000_000_000_000);
assert_op!(c - b == a);
}
#[test]
fn test_sub_with_carry() {
use std;
let a = BigUint::from(std::u32::MAX as u64);
let b = BigUint::from(1);
let c = BigUint::from(std::u32::MAX as u64 + 1);
assert_op!(c - b == a);
}
#[test]
fn test_mul() {
let a = BigUint::from(3);
let b = BigUint::from(2);
let c = BigUint::from(6);
assert_op!(a * b == c);
}
#[test]
fn test_mul_zero() {
let a = BigUint::zero();
let b = BigUint::one();
assert_op!(a * b == a);
assert_op!(a * a == a);
}
#[test]
fn test_mul_big() {
let a = BigUint::from(3_000_000_000_000);
let b = BigUint::from(2_000_000_000_000);
let c = BigUint::from(6_000_000_000_000);
let d = BigUint::from(1_000_000_000_000);
let e = &d * &c;
assert_op!(a * b == e);
}
#[test]
fn test_mul_with_carry() {
let a = BigUint::from(2);
let b = BigUint::from(1u64 << 31);
let c = BigUint::from(1u64 << 32);
assert_op!(a * b == c);
}
#[test]
fn test_cmp() {
let a = BigUint::from(3);
let b = BigUint::from(2);
let c = BigUint::zero();
assert!(a > b);
assert!(b < a);
assert!(a == a);
assert!(c == c);
assert!(a > c);
assert!(c < a);
}
#[test]
fn test_big_cmp() {
let a = BigUint::from(3_000_000_000_000u64);
let b = BigUint::from(2_000_000_000_000u64);
let c = BigUint::from(2_000_000_000_001u64);
assert!(a == a);
assert!(a > b);
assert!(b < a);
assert!(c > b);
assert!(b < c);
}
macro_rules! assert_from_str {
($a: expr, $b: expr) => {{
let a = BigUint::from_str($a).unwrap();
let b = BigUint::from($b);
assert_eq!(a, b);
}};
}
#[test]
fn test_from_str() {
use std::str::FromStr;
assert_from_str!("0", 0);
assert_from_str!("123", 123);
assert_from_str!("1000000000", 1000000000);
assert_from_str!("10000000000", 10000000000);
assert_from_str!("12345678901", 12345678901);
}
#[test]
fn test_from_str_big() {
use std::str::FromStr;
let base = BigUint::from(1000000000);
let a = &base * &base * &base;
assert_eq!(BigUint::from_str("1000000000000000000000000000"), Ok(a));
}
#[test]
fn test_fmt() {
use std::str::FromStr;
assert_eq!("0".to_string(), format!("{}", BigUint::from(0)));
assert_eq!("1".to_string(), format!("{}", BigUint::from(1)));
assert_eq!(
"123456789".to_string(),
format!("{}", BigUint::from(123456789))
);
assert_eq!(
"1000000001".to_string(),
format!("{}", BigUint::from(1000000001))
);
assert_eq!(
"12345678901".to_string(),
format!("{}", BigUint::from(12345678901))
);
assert_eq!(
"123456789012345678901234567890".to_string(),
format!(
"{}",
BigUint::from_str("123456789012345678901234567890").unwrap()
)
);
}
}
}
}
#[macro_use]
pub mod prelude {
pub use self::myvec::*;
#[macro_use]
pub mod primitive {
pub trait ToUsize: Sized {
fn to_usize(self) -> usize;
}
impl ToUsize for i32 {
#[inline]
fn to_usize(self) -> usize {
self as usize
}
}
impl ToUsize for i64 {
#[inline]
fn to_usize(self) -> usize {
self as usize
}
}
impl ToUsize for usize {
#[inline]
fn to_usize(self) -> usize {
self
}
}
}
#[macro_use]
pub mod myvec {
use std::fmt;
use std::iter::FromIterator;
use std::ops::*;
pub use super::primitive::ToUsize;
/// `Vec` indexable with `i32`, `i64` or `usize`.
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct MyVec<T>(pub Vec<T>);
/// Creates `MyVec`
#[macro_export]
macro_rules! v {
( $( $x:expr ),* ) => {
MyVec(vec![ $( $x, )* ])
};
( $x:expr ; $n:expr ) => {
{
MyVec(vec![$x; $n as usize])
}
};
}
impl<T: fmt::Display> fmt::Display for MyVec<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let n = self.len();
for i in 0..n {
let r = if i < n - 1 {
writeln!(f, "{}", self.0[i])
} else {
write!(f, "{}", self.0[i])
};
if r.is_err() {
return r;
}
}
Ok(())
}
}
impl<T> Deref for MyVec<T> {
type Target = Vec<T>;
#[inline]
fn deref(&self) -> &Vec<T> {
&self.0
}
}
impl<T> DerefMut for MyVec<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.0
}
}
impl<T> FromIterator<T> for MyVec<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
MyVec(Vec::from_iter(iter))
}
}
impl<T, I: ToUsize> Index<I> for MyVec<T> {
type Output = T;
#[inline]
fn index(&self, i: I) -> &T {
&self.0[i.to_usize()]
}
}
impl<T, I: ToUsize> IndexMut<I> for MyVec<T> {
#[inline]
fn index_mut(&mut self, i: I) -> &mut T {
&mut self.0[i.to_usize()]
}
}
#[test]
fn test_myvec() {
let mut x = v![3, 2, 1];
x.sort();
assert_eq!(vec![1, 2, 3], *x);
let i = 1i32;
assert_eq!(2, x[i]);
x[i] = 3;
assert_eq!(3, x[i]);
let u = 1usize;
assert_eq!(3, x[u]);
x[u] = 2;
assert_eq!(2, x[u]);
assert_eq!(2, x[1]);
assert_eq!("MyVec([1, 2, 3])", format!("{:?}", x));
assert_eq!(v![1, 2, 3], x);
assert_eq!("1\n2\n3", format!("{}", x));
let mut y = v![v![1, 2]; 3];
y[0][0] = 2;
assert_eq!(vec![2, 2], *y[0]);
assert_eq!(vec![1, 2], *y[1]);
}
}
}
#[macro_use]
pub mod io {
/// Scanner
///
/// # Example
/// ```
/// use contest::io::Scanner;
/// let mut sc = Scanner::new("1 2 \n\n \r\t \n 3".as_bytes());
/// assert_eq!("1".to_string(), sc.next::<String>());
/// let v = sc.nexts(2);
/// assert_eq!(2i32, v[0]);
/// assert_eq!(3i32, v[1]);
///
/// // To create a scanner from stdin:
/// Scanner::new(std::io::stdin());
/// ```
use std;
use std::io;
use std::io::BufRead;
use super::prelude::MyVec;
pub struct Scanner<R: io::Read> {
br: io::BufReader<R>,
// Read tokens are stored in reversed order per line.
buf: Vec<String>,
}
pub fn new<R: io::Read>(r: R) -> Scanner<R> {
Scanner::new(r)
}
impl<R: io::Read> Scanner<R> {
#[inline]
pub fn new(r: R) -> Scanner<R> {
Scanner {
br: io::BufReader::new(r),
buf: vec![],
}
}
#[inline]
pub fn next<T>(&mut self) -> T
where
T: std::str::FromStr,
T::Err: std::fmt::Debug,
{
self.next_string()
.map(|s| s.parse::<T>().expect("Parse failed: "))
.expect("Unexpected EOF")
}
#[inline]
pub fn nexts<T>(&mut self, n: i32) -> MyVec<T>
where
T: std::str::FromStr,
T::Err: std::fmt::Debug,
{
let mut res = v![];
for _ in 0..n {
res.push(self.next());
}
res
}
fn next_string(&mut self) -> Option<String> {
self.buf.pop().or_else(|| match self.update() {
true => self.next_string(),
false => None,
})
}
#[inline]
fn update(&mut self) -> bool {
let mut s = String::new();
let res = self.br.read_line(&mut s);
match res.expect("I/O error.") {
0 => false,
_ => {
self.buf = s.split_whitespace().map(|x| x.to_string()).rev().collect();
true
}
}
}
}
#[test]
fn test_next() {
let mut sc = new("hoge".as_bytes());
let s: String = sc.next();
assert_eq!("hoge", s);
}
}
}
//////////////////////////////// LIBRARY END ////////////////////////////////
use contest::io::Scanner;
use contest::num::BigUint;
use contest::prelude::MyVec;
fn main() {
let mut sc = Scanner::new(std::io::stdin());
let n = sc.next::<i32>();
for _ in 0..n {
let a = sc.next::<BigUint>();
let b = sc.next::<BigUint>();
let res = format!("{}", a + b);
if res.len() > 80 {
println!("overflow");
} else {
println!("{}", res);
}
}
}