結果

問題 No.1556 Power Equality
ユーザー へのく
提出日時 2021-06-25 21:52:12
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 1 ms / 2,000 ms
コード長 14,200 bytes
コンパイル時間 13,254 ms
コンパイル使用メモリ 378,828 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-06-25 09:47:26
合計ジャッジ時間 13,272 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 9
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#![allow(non_snake_case)]
use crate::{modulo::StaticModInt, scanner::Scanner};
const M1: u64 = 754_974_721;
const M2: u64 = 167_772_161;
const M3: u64 = 469_762_049;
modint!(M1);
modint!(M2);
modint!(M3);
type Z1 = StaticModInt<M1>;
type Z2 = StaticModInt<M1>;
type Z3 = StaticModInt<M1>;
fn main() {
let mut scan = Scanner::new();
let a = scan.long();
let b = scan.long();
println!(
"{}",
if Z1::new(a).pow(b) == Z1::new(b).pow(a)
&& Z2::new(a).pow(b) == Z2::new(b).pow(a)
&& Z3::new(a).pow(b) == Z3::new(b).pow(a)
{
"Yes"
} else {
"No"
}
);
}
pub mod scanner {
use std::io::{stdin, BufReader, Bytes, Read, Stdin};
use std::str::FromStr;
pub struct Scanner {
buf: Bytes<BufReader<Stdin>>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buf: BufReader::new(stdin()).bytes(),
}
}
#[inline]
fn token<T: std::iter::FromIterator<char>>(&mut self) -> T {
self.buf
.by_ref()
.map(|c| c.unwrap() as char)
.skip_while(|c| c.is_whitespace())
.take_while(|c| !c.is_whitespace())
.collect()
}
#[inline]
pub fn read<T: FromStr>(&mut self) -> T {
self.string().parse().ok().unwrap()
}
#[inline]
pub fn string(&mut self) -> String {
self.token()
}
#[inline]
pub fn long(&mut self) -> i64 {
self.read()
}
}
}
pub mod nums {
use std::mem::swap;
pub fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
let a = a.rem_euclid(b);
if a == 0 {
return (b, 0);
}
let mut s = b;
let mut t = a;
let mut m0 = 0;
let mut m1 = 1;
while t != 0 {
let u = s / t;
s -= t * u;
m0 -= m1 * u;
swap(&mut s, &mut t);
swap(&mut m0, &mut m1);
}
if m0 < 0 {
m0 += b / s;
}
(s, m0)
}
}
pub mod modulo {
use crate::nums::inv_gcd;
use crate::{impl_integer_functions, independent::integer::Int};
use std::cell::RefCell;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::*;
use std::sync::atomic::{self, AtomicU32};
use std::thread::LocalKey;
pub trait Modulus: 'static + PartialEq + Eq + Copy + Clone + std::hash::Hash + Ord {
const M: u32;
const HINT_M_IS_PRIME: bool;
fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>>;
}
pub trait DynamicModulus:
'static + PartialEq + Eq + Copy + Clone + std::hash::Hash + Ord
{
fn state() -> &'static AtomicU32 {
static M: AtomicU32 = AtomicU32::new(1_000_000_007);
&M
}
fn update(m: u32) {
Self::state().store(m, atomic::Ordering::SeqCst)
}
fn umod() -> u32 {
Self::state().load(atomic::Ordering::SeqCst)
}
}
#[derive(PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)]
pub enum DefaultId {}
impl DynamicModulus for DefaultId {}
macro_rules! impl_from_for_modint {
($name:ident, $guard: ident, $($tpe:ident),*) => {
$(
impl<T: $guard> From<$tpe> for $name<T> {
fn from(n: $tpe) -> Self {
Self::new(n)
}
}
)*
};
}
macro_rules! impl_assign {
($name:ident, $guard:ident, $($t1:ty, $t2:ty, $fa:ident, $f:ident),*) => {
$(
impl<T: $guard> $t1 for $name<T> {
type Output = Self;
#[inline]
fn $f(self, other: Self) -> Self {
<Self as ModInt>::$f(self, other)
}
}
impl<T: $guard> $t2 for $name<T> {
#[inline]
fn $fa(&mut self, other: Self) {
*self = <Self as ModInt>::$f(*self, other);
}
}
)*
};
}
macro_rules! impl_modint_structs {
($name:ident, $guard:ident) => {
#[derive(PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct $name<T> {
pub val: u32,
phantom: PhantomData<fn() -> T>,
}
impl<T> Debug for $name<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.val.fmt(f)
}
}
impl<T: $guard> $name<T> {
#[inline]
pub fn new<U: Int>(a: U) -> Self {
<Self as ModInt>::new(a)
}
#[inline]
pub fn inv(self) -> Self {
<Self as ModInt>::inv(self)
}
#[inline]
pub fn raw(val: u32) -> Self {
Self {
val,
phantom: PhantomData,
}
}
#[inline]
pub fn pow<U: Int>(self, x: U) -> Self {
<Self as ModInt>::pow(self, x)
}
#[inline]
pub fn zero() -> Self {
<Self as Int>::zero()
}
#[inline]
pub fn one() -> Self {
<Self as Int>::one()
}
}
impl<T> std::fmt::Display for $name<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.val)
}
}
impl_from_for_modint!(
$name, $guard, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize
);
impl_assign!(
$name, $guard, Add, AddAssign, add_assign, add, Sub, SubAssign, sub_assign, sub,
Mul, MulAssign, mul_assign, mul, Div, DivAssign, div_assign, div, Rem, RemAssign,
rem_assign, rem
);
impl<T: $guard> Int for $name<T> {
impl_integer_functions!(|s: &Self| s.val, |x| Self::new(x), |s: &Self, n: i64| s
.pow(n));
}
};
}
impl_modint_structs!(StaticModInt, Modulus);
impl_modint_structs!(DynamicModInt, DynamicModulus);
#[macro_export]
macro_rules! modint {
() => {$crate::modint!(1000000007, true);};
($m:literal) => {$crate::modint!($m, true);};
($m:literal, $is_prime:literal) => {
$crate::modint!($m, ModValue, $is_prime);
#[allow(dead_code)]
type Z = $crate::modulo::StaticModInt<ModValue>;
};
($name:ident) => {
$crate::modint!($name, $name, true);
};
($value:expr, $name:ident, $is_prime:literal) => {
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)]
pub enum $name {}
impl $crate::modulo::Modulus for $name {
const M: u32 = $value as _;
const HINT_M_IS_PRIME: bool = $is_prime;
fn butterfly_cache() -> &'static ::std::thread::LocalKey<::std::cell::RefCell<::std::option::Option<$crate::modulo::ButterflyCache
                    <Self>>>> {
thread_local! {
static BUTTERFLY_CACHE: ::std::cell::RefCell<::std::option::Option<$crate::modulo::ButterflyCache<$name>>> = ::std::default
                            ::Default::default();
}
&BUTTERFLY_CACHE
}
}
};
}
pub type D = DynamicModInt<DefaultId>;
pub trait ModInt: Int {
fn new<U: Int>(val: U) -> Self {
let x = val.to_i128();
Self::raw(x.rem_euclid(Self::modulus() as i128) as _)
}
fn inv(self) -> Self {
if Self::mod_is_prime() {
Self::pow(self, Self::modulus() - 2)
} else {
let (g, x) = inv_gcd(Self::val(self) as _, Self::modulus() as _);
if g != 1 {
panic!("the multiplicative inverse does not exist");
} else {
Self::new(x)
}
}
}
fn raw(val: u32) -> Self;
fn val(self) -> u32;
fn modulus() -> u32;
fn mod_is_prime() -> bool;
fn add(self, other: Self) -> Self {
let mut ret = self.val() + other.val();
if ret >= Self::modulus() {
ret -= Self::modulus();
}
Self::raw(ret)
}
fn sub(self, other: Self) -> Self {
let mut ret = self.val().wrapping_sub(other.val());
if ret >= Self::modulus() {
ret = ret.wrapping_add(Self::modulus());
}
Self::raw(ret)
}
fn mul(self, other: Self) -> Self {
Self::raw(
(u64::from(self.val()) * u64::from(other.val()) % u64::from(Self::modulus())) as _,
)
}
fn div(self, other: Self) -> Self {
self * other.inv()
}
fn rem(self, other: Self) -> Self {
Self::raw(self.val() % other.val())
}
fn pow<U: Int>(self, x: U) -> Self {
let mut n = x.to_i64();
let mut a = self;
let mut res = Self::raw(1);
while n > 0 {
if n & 1 == 1 {
res *= a;
}
a = a * a;
n >>= 1;
}
res
}
}
impl<M: Modulus> ModInt for StaticModInt<M> {
fn raw(val: u32) -> Self {
Self::raw(val)
}
fn val(self) -> u32 {
self.val
}
fn modulus() -> u32 {
M::M
}
fn mod_is_prime() -> bool {
M::HINT_M_IS_PRIME
}
}
impl<M: DynamicModulus> ModInt for DynamicModInt<M> {
fn raw(val: u32) -> Self {
Self::raw(val)
}
fn val(self) -> u32 {
self.val
}
fn modulus() -> u32 {
M::umod()
}
fn mod_is_prime() -> bool {
false
}
}
pub struct ButterflyCache<T> {
pub sum_e: Vec<StaticModInt<T>>,
pub sum_ie: Vec<StaticModInt<T>>,
}
}
pub mod independent {
pub mod integer {
use std::fmt::Display;
use std::ops::*;
pub trait Int:
Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
+ Rem<Output = Self>
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
+ RemAssign
+ std::hash::Hash
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Copy
+ Display
{
fn to_u8(&self) -> u8;
fn to_u16(&self) -> u16;
fn to_u32(&self) -> u32;
fn to_u64(&self) -> u64;
fn to_u128(&self) -> u128;
fn to_i8(&self) -> i8;
fn to_i16(&self) -> i16;
fn to_i32(&self) -> i32;
fn to_i64(&self) -> i64;
fn to_i128(&self) -> i128;
fn to_usize(&self) -> usize;
fn to_isize(&self) -> isize;
fn from_u8(x: u8) -> Self;
fn from_u16(x: u16) -> Self;
fn from_u32(x: u32) -> Self;
fn from_u64(x: u64) -> Self;
fn from_u128(x: u128) -> Self;
fn from_i8(x: i8) -> Self;
fn from_i16(x: i16) -> Self;
fn from_i32(x: i32) -> Self;
fn from_i64(x: i64) -> Self;
fn from_i128(x: i128) -> Self;
fn from_usize(x: usize) -> Self;
fn from_isize(x: isize) -> Self;
fn zero() -> Self;
fn one() -> Self;
fn next(&self) -> Self {
*self + Self::one()
}
fn powint(&self, n: i64) -> Self;
}
#[macro_export]
macro_rules! impl_integer_functions {
($to_op:expr, $from_op:expr, $pow:expr) => {
impl_integer_functions!(
$to_op, $from_op, $pow,
to_u8, from_u8, u8,
to_u16, from_u16, u16,
to_u32, from_u32, u32,
to_u64, from_u64, u64,
to_u128, from_u128, u128,
to_i8, from_i8, i8,
to_i16, from_i16, i16,
to_i32, from_i32, i32,
to_i64, from_i64, i64,
to_i128, from_i128, i128,
to_usize, from_usize, usize,
to_isize, from_isize, isize
);
};
($to_op:expr, $from_op:expr, $pow:expr, $($tofn:ident, $fromfn:ident, $tpe:ident),*) => {
$(
fn $tofn(&self) -> $tpe {
$to_op(self) as $tpe
}
fn $fromfn(x: $tpe) -> Self {
$from_op(x)
}
)*
fn zero() -> Self {$from_op(0)}
fn one() -> Self {$from_op(1)}
fn powint(&self, n: i64) -> Self {$pow(self, n)}
};
}
macro_rules! impl_integer {
($($tpe:ident),*) => {
$(
impl Int for $tpe {
impl_integer_functions!(
|s: &Self| *s, |x| x as $tpe, |s: &Self, n: i64| s.pow(n as u32)
);
}
)*
};
}
impl_integer!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize);
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0