結果
| 問題 |
No.885 アマリクエリ
|
| ユーザー |
akakimidori
|
| 提出日時 | 2020-10-26 20:22:25 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 62 ms / 2,000 ms |
| コード長 | 6,061 bytes |
| コンパイル時間 | 12,021 ms |
| コンパイル使用メモリ | 396,824 KB |
| 実行使用メモリ | 10,408 KB |
| 最終ジャッジ日時 | 2024-07-21 21:35:36 |
| 合計ジャッジ時間 | 14,591 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 19 |
ソースコード
// begin おためしbeats
pub trait Beats {
type Value: Clone;
fn merge(l: &Self::Value, r: &Self::Value) -> Self::Value;
fn propagate(p: &mut Self::Value, c: &mut [Self::Value]);
fn e() -> Self::Value;
}
pub trait Effect {
type Value;
type Query;
fn break_cond(x: &Self::Value, q: &Self::Query) -> bool;
fn tag_cond(x: &Self::Value, q: &Self::Query) -> bool;
fn update(x: &mut Self::Value, q: &Self::Query);
}
struct SegmentTreeBeats<R: Beats> {
size: usize,
val: Box<[R::Value]>,
dfs: Vec<(usize, usize, usize)>,
}
impl<R: Beats> SegmentTreeBeats<R> {
fn new(ini: &[R::Value]) -> Self {
let size = ini.len().next_power_of_two();
let val = vec![R::e(); 2 * size];
let mut val = val.into_boxed_slice();
val[size..(size + ini.len())].clone_from_slice(ini);
for i in (1..size).rev() {
val[i] = R::merge(&val[2 * i], &val[2 * i + 1]);
}
SegmentTreeBeats {
size,
val,
dfs: vec![],
}
}
fn update<E: Effect<Value = R::Value>>(&mut self, x: usize, y: usize, f: E::Query) {
assert!(x <= y && y <= self.size);
if x >= y {
return;
}
let val = &mut self.val;
self.dfs.push((1, 0, self.size));
while let Some((k, l, r)) = self.dfs.pop() {
if k > 2 * self.size {
let k = !k;
val[k] = R::merge(&val[2 * k], &val[2 * k + 1]);
continue;
}
if E::break_cond(&val[k], &f) {
continue;
}
if x <= l && r <= y && E::tag_cond(&val[k], &f) {
E::update(&mut val[k], &f);
continue;
}
let (a, b) = val.split_at_mut(2 * k);
R::propagate(&mut a[k], &mut b[..2]);
self.dfs.push((!k, l, r));
let m = (l + r) / 2;
if m < y {
self.dfs.push((2 * k + 1, m, r));
}
if x < m {
self.dfs.push((2 * k, l, m));
}
}
}
fn find(&mut self, x: usize, y: usize) -> R::Value {
assert!(x <= y && y <= self.size);
let mut res = R::e();
if x >= y {
return res;
}
let val = &mut self.val;
self.dfs.push((1, 0, self.size));
while let Some((k, l, r)) = self.dfs.pop() {
if x <= l && r <= y {
res = R::merge(&res, &val[k]);
continue;
}
let (a, b) = val.split_at_mut(2 * k);
R::propagate(&mut a[k], &mut b[..2]);
let m = (l + r) / 2;
if m < y {
self.dfs.push((2 * k + 1, m, r));
}
if x < m {
self.dfs.push((2 * k, l, m));
}
}
res
}
}
// end おためしbeats
// ---------- begin Scanner(require delimiter) ----------
mod scanner {
pub struct Scanner<R> {
reader: R,
buf: Vec<u8>,
}
#[allow(dead_code)]
impl<R: std::io::BufRead> Scanner<R> {
pub fn new(reader: R) -> Self {
Scanner {
reader: reader,
buf: Vec::with_capacity(1024),
}
}
fn read(&mut self, del: u8) {
self.buf.clear();
self.reader.read_until(del, &mut self.buf).ok();
assert!(self.buf.pop().unwrap() == del);
}
pub fn next<T: std::str::FromStr>(&mut self, del: u8) -> T {
self.read(del);
std::str::from_utf8(&self.buf)
.unwrap()
.trim()
.parse::<T>()
.ok()
.unwrap()
}
pub fn next_bytes(&mut self, del: u8) -> Vec<u8> {
self.read(del);
std::str::from_utf8(&self.buf)
.unwrap()
.trim()
.bytes()
.collect()
}
}
}
// ---------- end scanner(require delimiter) ----------
use std::io::Write;
fn main() {
let stdin = std::io::stdin();
let mut sc = scanner::Scanner::new(stdin.lock());
run(&mut sc);
}
#[derive(Clone)]
struct Value {
max: u64,
sum: u64,
len: u64,
}
struct Modulo;
impl Effect for Modulo {
type Value = Value;
type Query = u64;
fn break_cond(x: &Self::Value, q: &Self::Query) -> bool {
*q > x.max
}
fn tag_cond(x: &Self::Value, _: &Self::Query) -> bool {
x.max * x.len == x.sum
}
fn update(x: &mut Self::Value, q: &Self::Query) {
let v = x.max % *q;
x.max = v;
x.sum = v * x.len;
}
}
struct Yuki885;
impl Beats for Yuki885 {
type Value = Value;
fn merge(l: &Self::Value, r: &Self::Value) -> Self::Value {
Value {
max: std::cmp::max(l.max, r.max),
sum: l.sum + r.sum,
len: l.len + r.len,
}
}
fn propagate(p: &mut Self::Value, c: &mut [Self::Value]) {
let v = p.max;
if v * p.len == p.sum {
for c in c.iter_mut() {
c.max = v;
c.sum = v * c.len;
}
}
}
fn e() -> Self::Value {
Value {
max: 0,
sum: 0,
len: 0,
}
}
}
fn run<R: std::io::BufRead>(sc: &mut scanner::Scanner<R>) {
let out = std::io::stdout();
let mut out = std::io::BufWriter::new(out.lock());
let n: usize = sc.next(b'\n');
let mut ini = Vec::with_capacity(n);
for i in 0..n {
let d = if i == n - 1 {b'\n'} else {b' '};
let v: u64 = sc.next(d);
ini.push(Value {
max: v,
sum: v,
len: 1,
});
}
let mut seg = SegmentTreeBeats::<Yuki885>::new(&ini);
let q: usize = sc.next(b'\n');
for i in 0..q {
let d = if i == q - 1 {b'\n'} else {b' '};
let v: u64 = sc.next(d);
seg.update::<Modulo>(0, n, v);
writeln!(out, "{}", seg.find(0, n).sum).ok();
}
}
akakimidori