2023-09-28 お腹が痛い / PAST#8 N を解いた
お腹が痛い……。
- ジグザグな数列 (第八回 アルゴリズム実技検定:N問題)
https://atcoder.jp/contests/past202109-open/tasks/past202109_n- 提出: https://atcoder.jp/contests/past202109-open/submissions/46012056
- 解説 AC
- セグメント木の DP
- もらう形の DP をセグメント木で高速化する
- 使いまわす形での更新もしている
 
use std::{
    collections::{BTreeMap, BTreeSet},
    fmt::Display,
    ops::{Add, Sub},
};
use modint::ModInt1000000007 as ModInt;
use proconio::input;
use segtree::*;
use crate::internal_type_traits::Zero;
fn main() {
    input! {
        n: usize,
        a: [usize; n],
    }
    let map = a
        .iter()
        .copied()
        .collect::<BTreeSet<_>>()
        .into_iter()
        .enumerate()
        .fold(BTreeMap::new(), |mut m, (i, k)| {
            m.insert(k, i);
            m
        });
    #[derive(Clone, Copy)]
    struct M(ModInt);
    impl From<usize> for M {
        fn from(value: usize) -> Self {
            Self(ModInt::new(value))
        }
    }
    impl Add for M {
        type Output = M;
        fn add(self, rhs: Self) -> Self::Output {
            Self(self.0 + rhs.0)
        }
    }
    impl Display for M {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            self.0.fmt(f)
        }
    }
    impl Sub for M {
        type Output = M;
        fn sub(self, rhs: Self) -> Self::Output {
            Self(self.0 - rhs.0)
        }
    }
    impl Zero for M {
        fn zero() -> Self {
            M(ModInt::new(0))
        }
    }
    let mut zig = Segtree::<Additive<M>>::new(n);
    let mut zag = Segtree::<Additive<M>>::new(n);
    for a_i in a {
        let a_i = map[&a_i];
        let zig_p = zig.get(a_i);
        let zag_p = zag.get(a_i);
        zag.set(a_i, zag_p + zig.prod(0..a_i) + M::from(1));
        zig.set(a_i, zig_p + zag.prod(a_i + 1..n) + M::from(1));
    }
    let ans = zig.prod(0..) + zag.prod(0..) - M::from(2 * n);
    println!("{}", ans);
}
// modint
// segtree
今日のコミット。
- kireta 1 commit
- rust-atcoder 1 commit