complete 4674.rs 9912.rs 10826.rs 12140.rs 14452.rs 17021.rs 17386.rs 20929.rs

This commit is contained in:
2026-02-03 18:00:49 -08:00
parent de4d2c6afd
commit 8aee448a74
8 changed files with 692 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
use std::fmt::{Display, Formatter, Result};
use std::io::stdin;
use std::ops::Add;
const MAX_UUINT_CNT: usize = 128;
#[derive(Clone, Copy, Debug, PartialEq)]
struct UltraUInt {
data: [u64; MAX_UUINT_CNT],
}
impl UltraUInt {
const fn zero() -> Self {
UltraUInt {
data: [0; MAX_UUINT_CNT],
}
}
const fn from_u64(val: u64) -> Self {
let mut data = [0; MAX_UUINT_CNT];
data[0] = val;
UltraUInt { data }
}
fn is_high_masked(&self) -> bool {
if self.data[MAX_UUINT_CNT - 1] == u64::MAX {
true
} else {
false
}
}
const fn high_masked() -> Self {
let mut data = [0; MAX_UUINT_CNT];
data[MAX_UUINT_CNT - 1] = u64::MAX;
UltraUInt { data }
}
fn div_rem_u64(&mut self, divisor: u64) -> u64 {
let mut rem = 0u128;
for i in (0..MAX_UUINT_CNT).rev() {
let current = (self.data[i] as u128) + (rem << 64);
self.data[i] = (current / divisor as u128) as u64;
rem = current % divisor as u128;
}
rem as u64
}
fn is_zero(&self) -> bool {
self.data.iter().all(|&x| x == 0)
}
}
impl<'a, 'b> Add<&'b UltraUInt> for &'a UltraUInt {
type Output = UltraUInt;
fn add(self, rhs: &'b UltraUInt) -> Self::Output {
let mut new = [0; MAX_UUINT_CNT];
let mut carry = 0u128;
for i in 0..MAX_UUINT_CNT {
let s = (self.data[i] as u128) + (rhs.data[i] as u128) + carry;
new[i] = s as u64;
carry = s >> 64;
}
UltraUInt { data: new }
}
}
impl Display for UltraUInt {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if self.is_zero() {
return write!(f, "0");
}
let mut temp = *self;
let mut chunks = Vec::new();
let base = 10_000_000_000_000_000_000u64;
while !temp.is_zero() {
chunks.push(temp.div_rem_u64(base));
}
if let Some(last) = chunks.pop() {
write!(f, "{}", last)?;
}
for chunk in chunks.into_iter().rev() {
write!(f, "{:019}", chunk)?;
}
Ok(())
}
}
static mut F: [UltraUInt; 10001] = {
let mut arr: [UltraUInt; 10001] = [UltraUInt::high_masked(); 10001];
arr[0] = UltraUInt::from_u64(0);
arr[1] = UltraUInt::from_u64(1);
arr
};
fn fib(n: usize) -> UltraUInt {
unsafe {
for i in 2..=n {
F[i] = &F[i - 1] + &F[i - 2];
}
F[n]
}
}
fn main() {
let mut line = String::new();
stdin().read_line(&mut line).unwrap();
let n = line.trim().parse::<usize>().unwrap();
println!("{}", fib(n));
}

View File

@@ -0,0 +1,107 @@
use std::io::stdin;
#[derive(Clone, Copy, PartialEq)]
enum Cell {
Up,
Right,
Down,
Left,
Period,
}
fn cnt_minimum_changed_to_be_safe(r: usize, c: usize, field: &Vec<Vec<Cell>>) -> usize {
let mut res = 0;
let has_target = |row: usize, col: usize, dr: i32, dc: i32| -> bool {
let mut curr_r = row as i32 + dr;
let mut curr_c = col as i32 + dc;
while curr_r >= 0 && curr_r < r as i32 && curr_c >= 0 && curr_c < c as i32 {
if field[curr_r as usize][curr_c as usize] != Cell::Period {
return true;
}
curr_r += dr;
curr_c += dc;
}
false
};
for i in 0..r {
for j in 0..c {
let s = field[i][j];
if let Cell::Period = s {
continue;
}
let (dr, dc) = match s {
Cell::Up => (-1, 0),
Cell::Down => (1, 0),
Cell::Left => (0, -1),
Cell::Right => (0, 1),
Cell::Period => unreachable!(),
};
if has_target(i, j, dr, dc) {
continue;
}
let possible_dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)];
let can_be_saved = possible_dirs
.iter()
.any(|&(ndr, ndc)| has_target(i, j, ndr, ndc));
if can_be_saved {
res += 1;
} else {
return usize::MAX;
}
}
}
res
}
fn main() {
let mut line = String::new();
stdin().read_line(&mut line).unwrap();
let t = line.trim().parse::<usize>().unwrap();
(1..=t).for_each(|case| {
line.clear();
stdin().read_line(&mut line).unwrap();
let (r, c) = {
let mut iter = line.trim().split(' ').map(|x| x.parse::<usize>().unwrap());
(iter.next().unwrap(), iter.next().unwrap())
};
let field = (0..r)
.map(|_| {
line.clear();
stdin().read_line(&mut line).unwrap();
let row = line
.trim()
.chars()
.map(|c| match c {
'.' => Cell::Period,
'>' => Cell::Right,
'<' => Cell::Left,
'^' => Cell::Up,
'v' => Cell::Down,
_ => Cell::Period,
})
.collect::<Vec<Cell>>();
row
})
.collect::<Vec<Vec<Cell>>>();
let res = cnt_minimum_changed_to_be_safe(r, c, &field);
println!(
"Case #{}: {}",
case,
if res != usize::MAX {
res.to_string()
} else {
"IMPOSSIBLE".to_string()
}
)
});
}

View File

@@ -0,0 +1,48 @@
use std::{
cmp::{max, Reverse},
collections::BinaryHeap,
io::{read_to_string, stdin},
};
fn least_k(n: usize, durs: &Vec<usize>, tmax: usize) -> usize {
let mut lo = 1;
let mut hi = n;
let mut res = n;
while lo <= hi {
let mid = (lo + hi) / 2;
let mut elapsed = 0;
let mut heap: BinaryHeap<Reverse<usize>> = BinaryHeap::new();
for &d in durs[0..mid].iter() {
elapsed = max(elapsed, d);
heap.push(Reverse(d));
}
for &d in durs[mid..n].iter() {
let finished = heap.pop().unwrap().0;
heap.push(Reverse(finished + d));
elapsed = max(elapsed, finished + d);
}
if elapsed <= tmax {
res = mid;
hi = mid - 1;
} else {
lo = mid + 1;
}
}
res
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<usize>().unwrap());
let n = iter.next().unwrap();
let tmax = iter.next().unwrap();
let duration_orders: Vec<usize> = (0..n).map(|_| iter.next().unwrap()).collect();
println!("{}", least_k(n, &duration_orders, tmax));
}

View File

@@ -0,0 +1,169 @@
use std::io::{stdin, BufRead};
const R: usize = 1_000_000_007;
pub struct Scanner<R> {
reader: R,
buffer: Vec<String>,
}
impl<R: BufRead> Scanner<R> {
pub fn new(reader: R) -> Self {
Self {
reader,
buffer: vec![],
}
}
pub fn next(&mut self) -> Option<String> {
loop {
if let Some(token) = self.buffer.pop() {
return Some(token);
}
let mut line = String::new();
match self.reader.read_line(&mut line) {
Ok(0) => return None,
Ok(_) => {
self.buffer = line.split_whitespace().rev().map(String::from).collect();
}
Err(_) => return None,
}
}
}
pub fn next_usize(&mut self) -> Option<usize> {
self.next()?.parse().ok()
}
pub fn next_char(&mut self) -> Option<char> {
self.next()?.chars().next()
}
}
fn get_partial_sent(
partial_sent_count: &mut Vec<usize>,
cnt_words_by_syllables: &Vec<usize>,
curr: usize,
) -> usize {
if partial_sent_count[curr] != usize::MAX {
partial_sent_count[curr]
} else {
let mut s = 0;
for i in 1..=curr {
let cnt_words_at = cnt_words_by_syllables[i];
s += cnt_words_at
* get_partial_sent(partial_sent_count, cnt_words_by_syllables, curr - i);
s %= R;
}
partial_sent_count[curr] = s;
s
}
}
fn get_all_poems(
n: usize,
m: usize,
k: usize,
words: &Vec<(usize, usize)>,
rhyme_types: &[usize; 26],
) -> usize {
let mut total_sent_by_cat = vec![0; n];
let mut partial_sent_count = vec![usize::MAX; k];
partial_sent_count[0] = 1;
let mut cnt_words_by_syllables = vec![0; k + 1];
for &(s, _) in words.iter() {
cnt_words_by_syllables[s] += 1;
}
for &(s, c) in words.iter() {
let curr = k - s;
let s = get_partial_sent(&mut partial_sent_count, &cnt_words_by_syllables, curr);
total_sent_by_cat[c - 1] += s;
total_sent_by_cat[c - 1] %= R;
}
// Devide Powering
let mut pow2_memo = vec![vec![usize::MAX; 20]; n];
for i in 0..n {
let sent = total_sent_by_cat[i];
if sent == 0 {
continue;
}
let mut curr = sent;
pow2_memo[i][0] = 1;
for j in 1..20 {
pow2_memo[i][j] = curr;
curr = curr * curr;
curr %= R;
}
}
let fast_power = |idx: usize, n: usize| {
let x = total_sent_by_cat[idx];
if x == 0 {
return 0;
}
let mut curr = n;
let mut s = 1;
let mut i = 1;
while curr > 0 {
if curr & 1 == 1 {
s *= pow2_memo[idx][i];
s %= R;
}
curr >>= 1;
i += 1;
}
s
};
// Logic
let mut res = 1;
for &rhyme in rhyme_types.iter() {
if rhyme == 0 {
continue;
}
let s: usize = (0..n).map(|idx| fast_power(idx, rhyme)).sum::<usize>() % R;
res *= s;
res %= R;
}
res
}
fn main() {
let mut scan = Scanner::new(stdin().lock());
let (n, m, k) = (
scan.next_usize().unwrap(),
scan.next_usize().unwrap(),
scan.next_usize().unwrap(),
);
let words = (0..n)
.map(|_| (scan.next_usize().unwrap(), scan.next_usize().unwrap()))
.collect::<Vec<(usize, usize)>>();
let poem_structure = (0..m)
.map(|_| (scan.next_char().unwrap() as u8 - 'A' as u8) as usize)
.collect::<Vec<usize>>();
let rhyme_types = {
let mut rhyme_types = [0usize; 26];
for t in poem_structure {
rhyme_types[t] += 1;
}
rhyme_types
};
println!("{}", get_all_poems(n, m, k, &words, &rhyme_types))
}

View File

@@ -0,0 +1,68 @@
use std::io::{read_to_string, stdin};
pub struct Point {
x: f64,
y: f64,
}
pub struct Line {
p1: Point,
p2: Point,
}
fn ccw(p1: &Point, p2: &Point, p3: &Point) -> i32 {
let k = (p1.y - p2.y) * (p2.x - p3.x) - (p1.x - p2.x) * (p2.y - p3.y);
if k > 0.0 {
1
} else if k < 0.0 {
-1
} else {
0
}
}
fn check_intersect(l1: &Line, l2: &Line) -> bool {
let c1 = ccw(&l1.p1, &l1.p2, &l2.p1) * ccw(&l1.p1, &l1.p2, &l2.p2);
let c2 = ccw(&l2.p1, &l2.p2, &l1.p1) * ccw(&l2.p1, &l2.p2, &l1.p2);
if c1 <= 0 && c2 <= 0 {
true
} else {
false
}
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<f64>().unwrap());
let l1 = {
Line {
p1: Point {
x: iter.next().unwrap(),
y: iter.next().unwrap(),
},
p2: Point {
x: iter.next().unwrap(),
y: iter.next().unwrap(),
},
}
};
let l2 = {
Line {
p1: Point {
x: iter.next().unwrap(),
y: iter.next().unwrap(),
},
p2: Point {
x: iter.next().unwrap(),
y: iter.next().unwrap(),
},
}
};
println!("{}", check_intersect(&l1, &l2) as u8);
}

View File

@@ -0,0 +1,81 @@
use std::io::stdin;
struct InquireManager {
line: String,
}
impl InquireManager {
fn new() -> Self {
InquireManager {
line: String::new(),
}
}
fn inquire_to_a(&mut self, x: usize) -> usize {
println!("? A {}", x);
self.get()
}
fn inquire_to_b(&mut self, x: usize) -> usize {
println!("? B {}", x);
self.get()
}
fn get(&mut self) -> usize {
stdin().read_line(&mut self.line).unwrap();
let r = self.line.trim().parse::<usize>().unwrap();
self.line.clear();
r
}
}
fn main() {
let mut inq = InquireManager::new();
let n = inq.get();
let res = if n <= 4 {
let mut v = vec![];
for i in 1..=n {
v.push(inq.inquire_to_a(i));
v.push(inq.inquire_to_b(i));
}
v.sort();
v[n - 1]
} else {
let mut midpoint = 0;
let mut lo = 1;
let mut hi = n;
let mut a_of = 0;
let mut b_of = 0;
let mut a_hi = inq.inquire_to_a(n);
let mut b_hi = inq.inquire_to_b(n);
while lo < hi {
let mid = (hi + lo) / 2;
a_of = inq.inquire_to_a(mid);
b_of = inq.inquire_to_b(n - mid);
if a_of == b_of {
midpoint = a_of;
break;
} else if a_of > b_of {
hi = mid;
a_hi = a_of;
} else {
// a_of < b_of
lo = mid + 1;
b_hi = b_of;
}
}
if midpoint != 0 {
midpoint
} else {
if a_hi < b_hi {
a_hi
} else {
b_hi
}
}
};
println!("! {}", res);
}

View File

@@ -0,0 +1,51 @@
use std::io::stdin;
fn convert(text: Vec<char>) -> Vec<u64> {
text.into_iter()
.map(|x| match x {
'_' => 0,
'a'..='z' => (x as u8 - 'a' as u8 + 1) as u64,
'.' => 27,
_ => u64::MAX,
})
.collect()
}
fn revert(code: Vec<u64>) -> Vec<char> {
code.into_iter()
.map(|x| match x {
0 => '_',
1..=26 => (b'a' + x as u8 - 1) as char,
27 => '.',
_ => '*',
})
.collect()
}
fn decrypt(k: u64, ciphertext: Vec<char>) -> Vec<char> {
let n = ciphertext.len();
let ciphercode = convert(ciphertext);
let mut plaincode = vec![0u64; n];
for i in 0..n {
let j = ((k * i as u64) % n as u64) as usize;
plaincode[j] = ((ciphercode[i] as u64 + i as u64) % 28) as u64;
}
revert(plaincode)
}
fn main() {
let mut line = String::new();
loop {
line.clear();
stdin().read_line(&mut line).unwrap();
if line.starts_with("0") {
break;
}
let mut iter = line.split(' ');
let k = iter.next().unwrap().trim().parse::<u64>().unwrap();
let msg = iter.next().unwrap().trim().chars().collect();
println!("{}", decrypt(k, msg).into_iter().collect::<String>());
}
}

View File

@@ -0,0 +1,53 @@
use std::io::{read_to_string, stdin};
fn fact(x: usize) -> usize {
static F: [usize; 16] = [
1,
1,
2,
6,
24,
120,
720,
5040,
40320,
362880,
3628800,
39916800,
479001600,
6227020800,
87178291200,
1307674368000,
];
F[x]
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<usize>().unwrap());
let n = iter.next().unwrap();
let perm = (0..n).map(|_| iter.next().unwrap()).collect::<Vec<usize>>();
let mut vis = vec![false; n];
let mut res = 0;
for i in 0..n {
let k = perm[i];
let r = n - i - 1;
let mut cnt = 0;
for j in 0..k {
if !vis[j] {
cnt += 1;
}
}
res += fact(r) * cnt;
// cl
vis[k] = true;
}
println!("{}", res + 1);
}