結果
| 問題 |
No.789 範囲の合計
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-07-25 15:58:00 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 80 ms / 1,000 ms |
| コード長 | 4,705 bytes |
| コンパイル時間 | 13,529 ms |
| コンパイル使用メモリ | 377,008 KB |
| 実行使用メモリ | 9,344 KB |
| 最終ジャッジ日時 | 2024-07-02 06:05:33 |
| 合計ジャッジ時間 | 15,647 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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 enum Node<T: Monoid> {
Section(Box<Section<T>>),
Leaf(Leaf<T>),
None,
}
pub struct Section<T: Monoid> {
left: Node<T>,
right: Node<T>,
val: T,
}
pub struct Leaf<T: Monoid> {
i: usize,
val: T,
}
impl<T: Monoid> Leaf<T> {
fn new(i: usize, x: T) -> Self {
Leaf { i: i, val: x }
}
fn fold(&self) -> T { self.val.clone() }
}
impl<T: Monoid> Section<T> {
fn new() -> Self {
Section {
left: Node::None,
right: Node::None,
val: T::identity(),
}
}
fn fold(&self) -> T { self.val.clone() }
fn update(&mut self, i: usize, x: T, l: usize, r: usize) {
let m = (l + r) >> 1;
if i < m {
let left = self.left.take();
self.left = left.update(i, x, l, m);
}
else {
let right = self.right.take();
self.right = right.update(i, x, m, r);
}
self.val = self.left.fold().op(&self.right.fold());
}
}
impl<T: Monoid> Node<T> {
fn take(&mut self) -> Node<T> {
std::mem::replace(self, Node::None)
}
fn fold(&self) -> T {
match self {
&Node::Section(ref sec) => sec.as_ref().fold(),
&Node::Leaf(ref leaf) => leaf.fold(),
&Node::None => T::identity(),
}
}
fn update(self, i: usize, x: T, l: usize, r: usize) -> Self {
match self {
Node::Section(mut sec) => {
sec.as_mut().update(i, x, l, r);
Node::Section(sec)
}
Node::Leaf(leaf) => {
if leaf.i == i {
Node::Leaf(Leaf::new(i, x))
}
else {
let mut new_section = Section::new();
let m = (l + r) >> 1;
if leaf.i < m {
new_section.left = Node::Leaf(leaf);
}
else {
new_section.right = Node::Leaf(leaf);
}
new_section.update(i, x, l, r);
Node::Section(Box::new(new_section))
}
}
Node::None => {
Node::Leaf(Leaf::new(i, x))
}
}
}
fn range_fold(&self, a: usize, b: usize, l: usize, r: usize) -> T {
match self {
&Node::Section(ref sec) => {
if b <= l || r <= a { T::identity() }
else if a <= l && r <= b { sec.fold() }
else {
let m = (l + r) >> 1;
sec.left.range_fold(a, b, l, m).op(&sec.right.range_fold(a, b, m, r))
}
}
&Node::Leaf(ref leaf) => {
if a <= leaf.i && leaf.i < b { leaf.fold() }
else { T::identity() }
}
&Node::None => T::identity(),
}
}
}
pub struct DynamicSegmentTree<T: Monoid> {
root: Node<T>,
n: usize,
}
impl<T: Monoid> DynamicSegmentTree<T> {
pub fn new(sz: usize) -> Self {
let mut n = 1;
while n < sz { n = n << 1; }
DynamicSegmentTree {
root: Node::None,
n: n,
}
}
pub fn update(&mut self, i: usize, x: T) {
let r = self.root.take();
self.root = r.update(i, x, 0, self.n);
}
pub fn fold(&self, l: usize, r: usize) -> T {
self.root.range_fold(l, r, 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 {
let val = dyseg.fold(a, a + 1).op(&A(b));
dyseg.update(a, val);
}
else if query == 1 {
ans = ans.op(&dyseg.fold(a, b + 1));
}
}
println!("{}", ans.0);
}