結果

問題 No.2981 Pack Tree into Grid
ユーザー akakimidori
提出日時 2024-12-05 04:42:48
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 970 ms / 2,000 ms
コード長 10,268 bytes
コンパイル時間 15,674 ms
コンパイル使用メモリ 379,116 KB
実行使用メモリ 24,612 KB
最終ジャッジ日時 2024-12-05 04:43:09
合計ジャッジ時間 19,835 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 28
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: type alias `Set` is never used
   --> src/main.rs:204:6
    |
204 | type Set<T> = BTreeSet<T>;
    |      ^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: type alias `Deque` is never used
   --> src/main.rs:205:6
    |
205 | type Deque<T> = VecDeque<T>;
    |      ^^^^^

ソースコード

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

// ---------- begin mod vector ----------
mod modvector {
const MOD: u64 = (1u64 << 61) - 1;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
struct ModInt(u64);
impl std::ops::Add for ModInt {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
debug_assert!(self.0 < MOD && rhs.0 < MOD);
let mut d = self.0 + rhs.0;
if d >= MOD {
d -= MOD;
}
ModInt(d)
}
}
impl std::ops::Sub for ModInt {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
debug_assert!(self.0 < MOD && rhs.0 < MOD);
let mut d = self.0 + MOD - rhs.0;
if d >= MOD {
d -= MOD;
}
ModInt(d)
}
}
impl std::ops::Mul for ModInt {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
debug_assert!(self.0 < MOD && rhs.0 < MOD);
let v = self.0 as u128 * rhs.0 as u128;
let mut c = (v >> 61) as u64 + (v & MOD as u128) as u64;
if c >= MOD {
c -= MOD;
}
ModInt(c)
}
}
impl ModInt {
fn new(v: u64) -> Self {
ModInt(v % MOD)
}
fn zero() -> Self {
ModInt(0)
}
fn pow(&self, n: u64) -> Self {
let mut t = ModInt(1);
let mut s = *self;
let mut n = n;
while n > 0 {
if n & 1 == 1 {
t = t * s;
}
s = s * s;
n >>= 1;
}
t
}
fn inv(&self) -> Self {
assert!(self.0 > 0);
self.pow(MOD - 2)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct ModVector<const N: usize> {
val: [ModInt; N],
}
#[allow(dead_code)]
impl<const N: usize> ModVector<N> {
pub fn zero() -> Self {
ModVector {
val: [ModInt::zero(); N],
}
}
pub fn one() -> Self {
ModVector {
val: [ModInt::new(1); N],
}
}
pub fn new(v: &[u64]) -> Self {
assert!(v.len() >= N);
let mut ans = ModVector::zero();
for (x, a) in ans.val.iter_mut().zip(v.iter()) {
*x = ModInt::new(*a);
}
ans
}
pub fn single(v: u64) -> Self {
ModVector::new(&[v; N])
}
pub fn add(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a + *b;
}
ans
}
pub fn sub(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a - *b;
}
ans
}
pub fn mul(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a * *b;
}
ans
}
pub fn inv(&self) -> Self {
let mut ans = ModVector::zero();
for (x, a) in ans.val.iter_mut().zip(self.val.iter()) {
*x = a.inv();
}
ans
}
pub fn generate_random_rad() -> Self {
let mut rad = ModVector::zero();
for (i, v) in rad.val.iter_mut().enumerate() {
*v = ModInt::new(if i & 1 == 0 {
rand_time() as u64 + 2
} else {
rand_memory() as u64 + 2
});
}
rad
}
}
pub fn rand_time() -> u32 {
static mut X: u32 = 0;
unsafe {
if X == 0 {
use std::time::{SystemTime, UNIX_EPOCH};
X = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.subsec_nanos();
}
X ^= X << 13;
X ^= X >> 17;
X ^= X << 5;
X
}
}
pub fn rand_memory() -> u32 {
static mut X: u32 = 0;
unsafe {
if X == 0 {
X = Box::into_raw(Box::new("I hope this is a random number")) as u32;
}
X ^= X << 13;
X ^= X >> 17;
X ^= X << 5;
X
}
}
}
// ---------- end mod vector ----------
// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
use std::str::FromStr;
pub struct Scanner<'a> {
it: std::str::SplitWhitespace<'a>,
}
impl<'a> Scanner<'a> {
pub fn new(s: &'a String) -> Scanner<'a> {
Scanner {
it: s.split_whitespace(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
self.it.next().unwrap().parse::<T>().ok().unwrap()
}
pub fn next_bytes(&mut self) -> Vec<u8> {
self.it.next().unwrap().bytes().collect()
}
pub fn next_chars(&mut self) -> Vec<char> {
self.it.next().unwrap().chars().collect()
}
pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
(0..len).map(|_| self.next()).collect()
}
}
}
// ---------- end scannner ----------
use std::collections::*;
use std::io::Write;
type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;
fn main() {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
let mut sc = scanner::Scanner::new(&s);
let out = std::io::stdout();
let mut out = std::io::BufWriter::new(out.lock());
run(&mut sc, &mut out);
}
fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
let t: u32 = sc.next();
for _ in 0..t {
let n: usize = sc.next();
let mut e = vec![(0, 0, 0); n - 1];
for e in e.iter_mut() {
e.0 = sc.next::<usize>() - 1;
e.1 = sc.next::<usize>() - 1;
e.2 = sc.next::<usize>();
}
let h: usize = sc.next();
let _w: usize = sc.next();
let s = (0..h).map(|_| sc.next_bytes()).collect::<Vec<_>>();
if let Some(ans) = solve(e, s) {
writeln!(out, "Yes").ok();
for (a, b) in ans {
writeln!(out, "{} {}", a + 1, b + 1).ok();
}
} else {
writeln!(out, "No").ok();
}
}
}
type M = modvector::ModVector<2>;
fn solve(e: Vec<(usize, usize, usize)>, s: Vec<Vec<u8>>) -> Option<Vec<(usize, usize)>> {
let n = e.len() + 1;
let (v, e) = {
let mut id = n;
let mut edge = vec![];
for (a, b, w) in e {
let mut v = vec![a];
for _ in 1..w {
v.push(id);
id += 1;
}
v.push(b);
edge.extend(v.windows(2).map(|v| (v[0], v[1])));
}
(id, edge)
};
let (memo, u, f) = {
let mut id = 0;
let h = s.len();
let w = s[0].len();
let mut v = vec![vec![!0; w]; h];
for (v, s) in v.iter_mut().zip(s.iter()) {
for (v, s) in v.iter_mut().zip(s.iter()) {
if *s == b'#' {
*v = id;
id += 1;
}
}
}
let mut edge = vec![];
for i in 0..h {
for j in 0..w {
if i > 0 && v[i][j] < id && v[i - 1][j] < id {
edge.push((v[i][j], v[i - 1][j]));
}
if j > 0 && v[i][j] < id && v[i][j - 1] < id {
edge.push((v[i][j], v[i][j - 1]));
}
}
}
(v, id, edge)
};
let dep = (0..v.max(u))
.map(|_| M::generate_random_rad())
.collect::<Vec<_>>();
let mut g = vec![vec![]; v];
let mut h = vec![vec![]; u];
for &(a, b) in e.iter() {
g[a].push(b);
g[b].push(a);
}
for &(a, b) in f.iter() {
h[a].push(b);
h[b].push(a);
}
let mut dp = Map::new();
let hash = calc(0, 0, &g, &dep, &mut dp);
(0..u)
.find(|&u| calc(u, u, &h, &dep, &mut dp) == hash)
.map(|root| {
let mut inv_memo = Map::new();
for (i, memo) in memo.iter().enumerate() {
for (j, memo) in memo.iter().enumerate() {
inv_memo.insert(*memo, (i, j));
}
}
let mut res = vec![(0, 0); v];
let mut dfs = vec![(0, 0, root, root)];
while let Some((v, p, u, q)) = dfs.pop() {
res[v] = inv_memo[&u];
let mut hist = Map::new();
for &a in g[v].iter().filter(|a| **a != p) {
hist.entry(calc(a, v, &g, &dep, &mut dp))
.or_insert(vec![])
.push(a);
}
for &b in h[u].iter().filter(|a| **a != q) {
let a = hist
.entry(calc(b, u, &h, &dep, &mut dp))
.or_insert(vec![])
.pop()
.unwrap();
dfs.push((a, v, b, u));
}
}
res.truncate(n);
res
})
}
// (v, p, g), (depth, hash)
fn calc(
v: usize,
p: usize,
g: &[Vec<usize>],
depth: &[M],
dp: &mut Map<(usize, usize, *const [Vec<usize>]), (usize, M)>,
) -> (usize, M) {
if let Some(&(d, h)) = dp.get(&(v, p, g)) {
return (d, h);
}
let mut val = M::one();
let mut k = 0usize;
for &u in g[v].iter().filter(|e| **e != p) {
let (a, b) = calc(u, v, g, depth, dp);
val = val.mul(&b);
k = k.max(a + 1);
}
val = val.add(&depth[k]);
dp.insert((v, p, g), (k, val));
(k, val)
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0