結果
| 問題 |
No.789 範囲の合計
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-07-25 10:44:36 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 184 ms / 1,000 ms |
| コード長 | 3,460 bytes |
| コンパイル時間 | 13,296 ms |
| コンパイル使用メモリ | 384,876 KB |
| 実行使用メモリ | 34,688 KB |
| 最終ジャッジ日時 | 2024-07-02 05:58:41 |
| 合計ジャッジ時間 | 15,290 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 15 |
ソースコード
pub trait Magma: Sized + Clone {
fn op(&self, rhs: &Self) -> Self;
}
pub trait Associative: Magma {}
pub trait Unital: Magma {
fn identity() -> Self;
}
pub trait Monoid: Magma + Associative + Unital {}
impl<T: Magma + Associative + Unital> Monoid for T {}
pub struct Node<M: Monoid> {
left: Option<Box<Node<M>>>,
right: Option<Box<Node<M>>>,
val: M,
}
impl<M: Monoid> Node<M> {
fn new() -> Self {
Node {
left: None,
right: None,
val: M::identity(),
}
}
}
pub fn value<M: Monoid>(node: &Option<Box<Node<M>>>) -> M {
match node.as_ref() {
Some(n) => n.as_ref().val.clone(),
None => M::identity()
}
}
pub fn update_node<M: Monoid>(node: &mut Node<M>, i: usize, x: M, l: usize, r: usize) {
if l + 1 == r {
node.val = x;
}
else {
let m = (l + r) >> 1;
if i < m {
{
if node.left.is_none() {
node.left = Some(Box::new(Node::new()));
}
let left = node.left.as_mut().unwrap().as_mut();
update_node(left, i, x, l, m);
}
}
else {
{
if node.right.is_none() {
node.right = Some(Box::new(Node::new()));
}
let right = node.right.as_mut().unwrap().as_mut();
update_node(right, i, x, m, r);
}
}
node.val = value(&node.left).op(&value(&node.right));
}
}
pub fn fold<M: Monoid>(node: &Node<M>, a: usize, b: usize, l: usize, r: usize) -> M {
if a <= l && r <= b { node.val.clone() }
else if r <= a || b <= l { M::identity() }
else {
match node.left.as_ref() {
Some(le) => fold(le, a, b, l, (l + r) >> 1),
None => M::identity(),
}.op(& match node.right.as_ref() {
Some(ri) => fold(ri, a, b, (l + r) >> 1, r),
None => M::identity(),
})
}
}
pub struct DynamicSegmentTree<M: Monoid> {
root: Node<M>,
n: usize,
}
impl<M: Monoid> DynamicSegmentTree<M> {
pub fn new(n: usize) -> Self {
let mut sz = 1;
while sz < n { sz = sz << 1; }
DynamicSegmentTree {
root: Node::new(),
n: sz
}
}
pub fn update(&mut self, i: usize, x: M) {
update_node(&mut self.root, i, x, 0, self.n);
}
pub fn fold(&self, a: usize, b: usize) -> M {
fold(&self.root, a, b, 0, self.n)
}
}
#[derive(Clone)]
struct A(usize);
impl Magma for A {
fn op(&self, a: &Self) -> Self { A(self.0 + a.0) }
}
impl Associative for A {}
impl Unital for A {
fn identity() -> Self { A(0) }
}
use std::io::Read;
fn main() {
let mut buf = String::new();
std::io::stdin().read_to_string(&mut buf).unwrap();
let mut iter = buf.split_whitespace();
let q: usize = iter.next().unwrap().parse().unwrap();
let mut dyseg = DynamicSegmentTree::<A>::new(1_000_000_100);
let mut ans = A(0);
for _ in 0..q {
let query: usize = iter.next().unwrap().parse().unwrap();
let a: usize = iter.next().unwrap().parse().unwrap();
let b: usize = iter.next().unwrap().parse().unwrap();
if query == 0 {
dyseg.update(a, dyseg.fold(a, a + 1).op(&A(b)));
}
else if query == 1 {
ans = ans.op(&dyseg.fold(a, b + 1));
}
}
println!("{}", ans.0);
}