結果

問題 No.3265 地元に帰れば天才扱い!
ユーザー urectanc
提出日時 2025-09-06 14:50:33
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 521 ms / 2,500 ms
コード長 10,887 bytes
コンパイル時間 19,249 ms
コンパイル使用メモリ 384,512 KB
実行使用メモリ 30,624 KB
最終ジャッジ日時 2025-09-06 14:51:14
合計ジャッジ時間 32,573 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 21
権限があれば一括ダウンロードができます

ソースコード

diff #

use bit::BinaryIndexedTree;
use lazy_segtree::{LazySegmentTree, Operator};
use proconio::{input, marker::Usize1};
use std::io::Write;

fn main() {
    input! {
        n: usize, m: usize,
        mut alr: [(i64, Usize1, usize); n],
        q: usize,
        queries: [(Usize1, Usize1, Usize1, usize); q],
    }
    let mut stdout = std::io::BufWriter::new(std::io::stdout().lock());

    let mut pos = (0..n).collect::<Vec<_>>();
    let mut bit_sum = BinaryIndexedTree::new(m, 0);
    let mut init = vec![0; m + 1];

    for (i, &(a, l, r)) in alr.iter().enumerate() {
        bit_sum.add(i, a);
        init[l] += 1;
        init[r] -= 1;
    }
    for i in 0..m {
        init[i + 1] += init[i];
    }

    let mut seg_cover = LazySegmentTree::<O>::from(init);

    let mut score = 0;
    for &(a, l, r) in &alr {
        let sum = bit_sum.sum(l, r);
        score += a * (r - l) as i64 - sum;
    }

    for &(x, to, u, v) in &queries {
        let (a, l, r) = alr[x];
        let from = pos[x];
        pos[x] = to;

        score -= a * (r - l) as i64;
        alr[x] = (a, u, v);
        score += a * (v - u) as i64;

        let sum = bit_sum.sum(l, r);
        score += sum;
        bit_sum.add(from, -a);
        bit_sum.add(to, a);
        let sum = bit_sum.sum(u, v);
        score -= sum;

        seg_cover.apply_range(l, r, -1);
        let cover = seg_cover.get(from);
        score += cover * a;
        let cover = seg_cover.get(to);
        score -= cover * a;
        seg_cover.apply_range(u, v, 1);

        writeln!(stdout, "{score}").unwrap();
    }
}

struct O;

impl Operator for O {
    type Value = i64;
    type Map = i64;

    fn identity() -> Self::Value {
        0
    }

    fn identity_map() -> Self::Map {
        0
    }

    fn op(_a: &Self::Value, _b: &Self::Value) -> Self::Value {
        0
    }

    fn apply(f: &Self::Map, x: &Self::Value) -> Self::Value {
        *x + *f
    }

    fn compose(f: &Self::Map, g: &Self::Map) -> Self::Map {
        *f + *g
    }
}

#[allow(dead_code)]
mod bit {
    pub struct BinaryIndexedTree<T> {
        n: usize,
        array: Vec<T>,
        e: T,
    }

    impl<T> BinaryIndexedTree<T>
    where
        T: Clone + std::ops::AddAssign + std::ops::Sub<Output = T> + std::cmp::PartialOrd,
    {
        pub fn new(n: usize, e: T) -> Self {
            Self {
                n,
                array: vec![e.clone(); n + 1],
                e,
            }
        }

        pub fn add(&mut self, i: usize, x: T) {
            let mut i = i + 1;
            while i <= self.n {
                self.array[i] += x.clone();
                i += i & i.wrapping_neg();
            }
        }

        pub fn cum(&self, mut i: usize) -> T {
            let mut cum = self.e.clone();
            while i > 0 {
                cum += self.array[i].clone();
                i -= i & i.wrapping_neg();
            }
            cum
        }

        pub fn sum(&self, l: usize, r: usize) -> T {
            self.cum(r) - self.cum(l)
        }

        pub fn lower_bound(&self, mut x: T) -> usize {
            let mut i = 0;
            let mut k = 1 << (self.n.next_power_of_two().trailing_zeros());
            while k > 0 {
                if i + k <= self.n && self.array[i + k] < x {
                    x = x - self.array[i + k].clone();
                    i += k;
                }
                k >>= 1;
            }
            i
        }
    }
}

#[allow(dead_code)]
mod lazy_segtree {
    pub trait Operator {
        type Value: Clone;
        type Map: Clone;

        fn identity() -> Self::Value;
        fn identity_map() -> Self::Map;
        fn op(a: &Self::Value, b: &Self::Value) -> Self::Value;
        fn apply(f: &Self::Map, x: &Self::Value) -> Self::Value;
        fn compose(f: &Self::Map, g: &Self::Map) -> Self::Map;
    }

    pub struct LazySegmentTree<O: Operator> {
        n: usize,
        offset: usize,
        height: usize,
        value: Vec<O::Value>,
        map: Vec<O::Map>,
    }

    impl<O: Operator> From<Vec<O::Value>> for LazySegmentTree<O> {
        fn from(v: Vec<O::Value>) -> Self {
            let n = v.len();
            let offset = n.next_power_of_two();
            let height = offset.trailing_zeros() as usize;
            let mut value = vec![O::identity(); 2 * offset];
            value[offset..][..n].clone_from_slice(&v);
            let map = vec![O::identity_map(); offset];
            let mut ret = Self {
                n,
                offset,
                height,
                value,
                map,
            };
            for i in (1..offset).rev() {
                ret.update(i);
            }
            ret
        }
    }

    impl<O: Operator> LazySegmentTree<O> {
        pub fn new(n: usize) -> Self {
            vec![O::identity(); n].into()
        }

        pub fn as_slice(&mut self) -> &[O::Value] {
            for i in 1..self.offset {
                self.push(i);
            }
            &self.value[self.offset..][..self.n]
        }

        pub fn get(&mut self, i: usize) -> O::Value {
            debug_assert!(i < self.n);
            let i = i + self.offset;
            for k in (1..=self.height).rev() {
                self.push(i >> k);
            }
            self.value[i].clone()
        }

        pub fn set(&mut self, i: usize, x: O::Value) {
            debug_assert!(i < self.n);
            let i = i + self.offset;
            for k in (1..=self.height).rev() {
                self.push(i >> k);
            }
            self.value[i] = x;
            for k in 1..=self.height {
                self.update(i >> k);
            }
        }

        pub fn prod(&mut self, l: usize, r: usize) -> O::Value {
            debug_assert!(l <= r && r <= self.n);
            let (mut l, mut r) = (l + self.offset, r + self.offset);

            for k in (1..=self.height).rev() {
                if ((l >> k) << k) != l {
                    self.push(l >> k);
                }
                if ((r >> k) << k) != r {
                    self.push(r >> k);
                }
            }

            let mut prod_l = O::identity();
            let mut prod_r = O::identity();
            while l < r {
                if l & 1 == 1 {
                    prod_l = O::op(&prod_l, &self.value[l]);
                    l += 1;
                }
                if r & 1 == 1 {
                    prod_r = O::op(&self.value[r - 1], &prod_r);
                }
                l >>= 1;
                r >>= 1;
            }

            O::op(&prod_l, &prod_r)
        }

        pub fn all_prod(&self) -> O::Value {
            self.value[1].clone()
        }

        pub fn apply(&mut self, i: usize, f: O::Map) {
            debug_assert!(i < self.n);
            let i = i + self.offset;
            for k in (1..=self.height).rev() {
                self.push(i >> k);
            }
            self.value[i] = O::apply(&f, &self.value[i]);
            for k in 1..=self.height {
                self.update(i >> k);
            }
        }

        pub fn apply_range(&mut self, l: usize, r: usize, f: O::Map) {
            debug_assert!(l <= r && r <= self.n);
            let (l, r) = (l + self.offset, r + self.offset);

            for k in (1..=self.height).rev() {
                if ((l >> k) << k) != l {
                    self.push(l >> k);
                }
                if ((r >> k) << k) != r {
                    self.push(r >> k);
                }
            }

            {
                let (mut l, mut r) = (l, r);
                while l < r {
                    if l & 1 == 1 {
                        self.all_apply(l, &f);
                        l += 1;
                    }
                    if r & 1 == 1 {
                        self.all_apply(r - 1, &f);
                    }
                    l >>= 1;
                    r >>= 1;
                }
            }

            for k in 1..=self.height {
                if ((l >> k) << k) != l {
                    self.update(l >> k);
                }
                if ((r >> k) << k) != r {
                    self.update(r >> k);
                }
            }
        }

        pub fn max_right(&mut self, l: usize, f: impl Fn(&O::Value) -> bool) -> usize {
            debug_assert!(l <= self.n);
            debug_assert!(f(&O::identity()));

            let mut i = l + self.offset;

            for k in (1..=self.height).rev() {
                self.push(i >> k);
            }

            let mut prod = O::identity();
            loop {
                i >>= i.trailing_zeros();
                let next = O::op(&prod, &self.value[i]);
                if !f(&next) {
                    break;
                }
                i += 1;
                prod = next;
                if i & i.wrapping_neg() == i {
                    return self.n;
                }
            }
            while i < self.offset {
                self.push(i);
                i *= 2;
                let next = O::op(&prod, &self.value[i]);
                if f(&next) {
                    i += 1;
                    prod = next;
                }
            }
            i - self.offset
        }

        pub fn min_left(&mut self, r: usize, f: impl Fn(&O::Value) -> bool) -> usize {
            debug_assert!(r <= self.n);
            debug_assert!(f(&O::identity()));

            let mut i = r + self.offset;

            for k in (1..=self.height).rev() {
                self.push((i - 1) >> k);
            }

            let mut prod = O::identity();
            loop {
                i >>= i.trailing_zeros();
                if i > 1 {
                    i -= 1;
                }
                let next = O::op(&self.value[i], &prod);
                if !f(&next) {
                    break;
                }
                prod = next;
                if i & i.wrapping_neg() == i {
                    return 0;
                }
            }
            while i < self.offset {
                self.push(i);
                i = 2 * i + 1;
                let next = O::op(&self.value[i], &prod);
                if f(&next) {
                    i -= 1;
                    prod = next;
                }
            }
            i + 1 - self.offset
        }

        fn update(&mut self, i: usize) {
            self.value[i] = O::op(&self.value[2 * i], &self.value[2 * i + 1]);
        }

        fn all_apply(&mut self, i: usize, f: &O::Map) {
            self.value[i] = O::apply(f, &self.value[i]);
            if i < self.offset {
                self.map[i] = O::compose(f, &self.map[i]);
            }
        }

        fn push(&mut self, i: usize) {
            let f = std::mem::replace(&mut self.map[i], O::identity_map());
            self.all_apply(2 * i, &f);
            self.all_apply(2 * i + 1, &f);
        }
    }
}
0