complete 11505.rs 16978.rs 26209.rs

This commit is contained in:
2026-04-04 20:49:49 +09:00
parent 9b79eb05ba
commit 798eb9482a
3 changed files with 332 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
use std::io::{BufWriter, Write, read_to_string, stdin, stdout};
const MOD: usize = 1_000_000_007;
/*
IMPLEMENTATION MONOID-FN
*/
pub trait MonoidFn<T> {
fn call(&self, a: &T, b: &T) -> T;
fn identity(&self) -> T;
}
/*
IMPLEMENTATION SEG-TREE ON MONOID-FN<T>
*/
struct SegTree<T: Clone, F>
where
F: MonoidFn<T>,
{
pub op: F,
size: usize,
tree: Vec<T>,
}
impl<T: Clone, F> SegTree<T, F>
where
F: MonoidFn<T>,
{
fn new(arr: &Vec<T>, op: F) -> Self {
let size = arr.len();
let mut tree = vec![op.identity(); size * 4];
let mut stack = vec![]; // (inst, index, [lo, hi))
stack.push((1, 0, 0, size)); // 빼면서 업데이트
stack.push((0, 0, 0, size)); // 넣기
while !stack.is_empty() {
let (inst, index, lo, hi) = stack.pop().unwrap();
if inst == 0 {
if hi - lo == 1 {
tree[index] = arr[lo].clone();
} else {
let mid = (lo + hi) / 2;
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
stack.push((1, left_index, lo, mid));
stack.push((0, left_index, lo, mid));
stack.push((1, right_index, mid, hi));
stack.push((0, right_index, mid, hi));
}
} else {
if hi - lo == 1 {
continue;
} else {
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
tree[index] = op.call(&tree[left_index], &tree[right_index]);
}
}
}
SegTree { op, size, tree }
}
fn query(&self, idx: usize, lo: usize, hi: usize, qlo: usize, qhi: usize) -> T {
if qlo >= hi || qhi <= lo {
self.op.identity()
} else if qlo <= lo && hi <= qhi {
self.tree[idx].clone()
} else {
let mid = (lo + hi) / 2;
let left_value = self.query(idx * 2 + 1, lo, mid, qlo, qhi);
let right_value = self.query(idx * 2 + 2, mid, hi, qlo, qhi);
self.op.call(&left_value, &right_value)
}
}
fn modify(&mut self, idx: usize, lo: usize, hi: usize, pos: usize, val: &T) {
if pos < lo || pos >= hi {
return;
}
if hi - lo == 1 {
self.tree[idx] = val.clone();
return;
}
let mid = (lo + hi) / 2;
self.modify(idx * 2 + 1, lo, mid, pos, val);
self.modify(idx * 2 + 2, mid, hi, pos, val);
self.tree[idx] = self
.op
.call(&self.tree[idx * 2 + 1], &self.tree[idx * 2 + 2]);
}
}
struct MulMod;
impl MonoidFn<usize> for MulMod {
fn call(&self, a: &usize, b: &usize) -> usize {
(a * b) % MOD
}
fn identity(&self) -> usize {
1
}
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<usize>().unwrap());
let (n, m, k) = (
iter.next().unwrap(),
iter.next().unwrap(),
iter.next().unwrap(),
);
let op = MulMod;
let arr = (0..n).map(|_| iter.next().unwrap()).collect::<Vec<_>>();
let mut out = BufWriter::new(stdout());
let mut segtr = SegTree::new(&arr, op);
for _ in 0..m + k {
let (a, b, c) = (
iter.next().unwrap(),
iter.next().unwrap() - 1,
iter.next().unwrap(),
);
if a == 2 {
let res = segtr.query(0, 0, n, b, c);
writeln!(out, "{}", res).unwrap();
} else {
segtr.modify(0, 0, n, b, &c);
}
}
}

View File

@@ -0,0 +1,174 @@
use std::io::{BufWriter, Write, read_to_string, stdin, stdout};
/*
IMPLEMENTATION MONOID-FN
*/
pub trait MonoidFn<T> {
fn call(&self, a: &T, b: &T) -> T;
fn identity(&self) -> T;
}
/*
IMPLEMENTATION SEG-TREE ON MONOID-FN<T>
*/
struct SegTree<T: Clone, F>
where
F: MonoidFn<T>,
{
pub op: F,
size: usize,
tree: Vec<T>,
}
impl<T: Clone, F> SegTree<T, F>
where
F: MonoidFn<T>,
{
fn new(arr: &Vec<T>, op: F) -> Self {
let size = arr.len();
let mut tree = vec![op.identity(); size * 4];
let mut stack = vec![]; // (inst, index, [lo, hi))
stack.push((1, 0, 0, size)); // 빼면서 업데이트
stack.push((0, 0, 0, size)); // 넣기
while !stack.is_empty() {
let (inst, index, lo, hi) = stack.pop().unwrap();
if inst == 0 {
if hi - lo == 1 {
tree[index] = arr[lo].clone();
} else {
let mid = (lo + hi) / 2;
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
stack.push((1, left_index, lo, mid));
stack.push((0, left_index, lo, mid));
stack.push((1, right_index, mid, hi));
stack.push((0, right_index, mid, hi));
}
} else {
if hi - lo == 1 {
continue;
} else {
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
tree[index] = op.call(&tree[left_index], &tree[right_index]);
}
}
}
SegTree { op, size, tree }
}
fn query(&self, idx: usize, lo: usize, hi: usize, qlo: usize, qhi: usize) -> T {
if qlo >= hi || qhi <= lo {
self.op.identity()
} else if qlo <= lo && hi <= qhi {
self.tree[idx].clone()
} else {
let mid = (lo + hi) / 2;
let left_value = self.query(idx * 2 + 1, lo, mid, qlo, qhi);
let right_value = self.query(idx * 2 + 2, mid, hi, qlo, qhi);
self.op.call(&left_value, &right_value)
}
}
fn modify(&mut self, idx: usize, lo: usize, hi: usize, pos: usize, val: &T) {
if pos < lo || pos >= hi {
return;
}
if hi - lo == 1 {
self.tree[idx] = val.clone();
return;
}
let mid = (lo + hi) / 2;
self.modify(idx * 2 + 1, lo, mid, pos, val);
self.modify(idx * 2 + 2, mid, hi, pos, val);
self.tree[idx] = self
.op
.call(&self.tree[idx * 2 + 1], &self.tree[idx * 2 + 2]);
}
}
struct MonoSum;
impl MonoidFn<i64> for MonoSum {
fn call(&self, a: &i64, b: &i64) -> i64 {
a + b
}
fn identity(&self) -> i64 {
0
}
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<i64>().unwrap());
let n = iter.next().unwrap() as usize;
let op = MonoSum;
let arr = (0..n).map(|_| iter.next().unwrap()).collect::<Vec<_>>();
let mut out = BufWriter::new(stdout());
let mut segtr = SegTree::new(&arr, op);
let mut m_queries = vec![];
let mut f_queries = vec![];
let m = iter.next().unwrap() as usize;
let mut cnt = 0;
for _ in 0..m {
let i = iter.next().unwrap();
if i == 2 {
f_queries.push((
iter.next().unwrap() as usize,
iter.next().unwrap() as usize - 1,
iter.next().unwrap() as usize,
cnt,
));
cnt += 1;
} else {
m_queries.push((iter.next().unwrap() as usize - 1, iter.next().unwrap()))
}
}
f_queries.sort_by_key(|v| v.0);
let mut curr = 0 as usize;
let mut f_ptr = 0;
let mf = f_queries.len();
let mut responses = vec![];
while f_ptr < mf {
let (k, ql, qr, cr) = f_queries[f_ptr];
while curr < k {
let (mpos, mv) = m_queries[curr];
segtr.modify(0, 0, n, mpos, &mv);
curr += 1;
}
if k == curr {
let res = segtr.query(0, 0, n, ql, qr);
responses.push((cr, res));
}
f_ptr += 1;
}
responses.sort_by_key(|x| x.0);
for res in responses {
writeln!(out, "{}", res.1).unwrap();
}
}

View File

@@ -0,0 +1,15 @@
use std::io::{read_to_string, stdin};
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<usize>().unwrap());
let arr = (0..8).map(|_| iter.next().unwrap()).collect::<Vec<_>>();
if arr.iter().any(|&x| x == 9) {
println!("F");
} else {
println!("S");
}
}