結果

問題 No.738 平らな農地
ユーザー koba-e964koba-e964
提出日時 2021-09-28 11:01:44
言語 Rust
(1.77.0)
結果
AC  
実行時間 343 ms / 2,000 ms
コード長 7,838 bytes
コンパイル時間 7,599 ms
コンパイル使用メモリ 152,456 KB
実行使用メモリ 8,512 KB
最終ジャッジ日時 2023-09-21 21:00:09
合計ジャッジ時間 20,572 ms
ジャッジサーバーID
(参考情報)
judge14 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,328 KB
testcase_01 AC 1 ms
4,332 KB
testcase_02 AC 1 ms
4,332 KB
testcase_03 AC 1 ms
4,332 KB
testcase_04 AC 2 ms
4,332 KB
testcase_05 AC 3 ms
4,332 KB
testcase_06 AC 3 ms
4,332 KB
testcase_07 AC 4 ms
4,328 KB
testcase_08 AC 2 ms
4,328 KB
testcase_09 AC 1 ms
4,332 KB
testcase_10 AC 1 ms
4,332 KB
testcase_11 AC 3 ms
4,328 KB
testcase_12 AC 2 ms
4,332 KB
testcase_13 AC 3 ms
4,328 KB
testcase_14 AC 2 ms
4,336 KB
testcase_15 AC 164 ms
4,496 KB
testcase_16 AC 164 ms
4,472 KB
testcase_17 AC 141 ms
4,328 KB
testcase_18 AC 142 ms
4,380 KB
testcase_19 AC 97 ms
4,332 KB
testcase_20 AC 166 ms
4,492 KB
testcase_21 AC 148 ms
4,332 KB
testcase_22 AC 164 ms
4,332 KB
testcase_23 AC 138 ms
4,336 KB
testcase_24 AC 118 ms
4,328 KB
testcase_25 AC 2 ms
4,332 KB
testcase_26 AC 2 ms
4,332 KB
testcase_27 AC 2 ms
4,332 KB
testcase_28 AC 2 ms
4,328 KB
testcase_29 AC 2 ms
4,332 KB
testcase_30 AC 2 ms
4,328 KB
testcase_31 AC 2 ms
4,332 KB
testcase_32 AC 2 ms
4,332 KB
testcase_33 AC 2 ms
4,332 KB
testcase_34 AC 2 ms
4,332 KB
testcase_35 AC 2 ms
4,328 KB
testcase_36 AC 2 ms
4,332 KB
testcase_37 AC 2 ms
4,332 KB
testcase_38 AC 2 ms
4,328 KB
testcase_39 AC 2 ms
4,332 KB
testcase_40 AC 2 ms
4,328 KB
testcase_41 AC 2 ms
4,332 KB
testcase_42 AC 2 ms
4,332 KB
testcase_43 AC 2 ms
4,332 KB
testcase_44 AC 2 ms
4,380 KB
testcase_45 AC 172 ms
5,600 KB
testcase_46 AC 155 ms
4,760 KB
testcase_47 AC 168 ms
5,276 KB
testcase_48 AC 155 ms
5,524 KB
testcase_49 AC 164 ms
5,548 KB
testcase_50 AC 162 ms
6,088 KB
testcase_51 AC 172 ms
5,004 KB
testcase_52 AC 160 ms
5,008 KB
testcase_53 AC 158 ms
5,052 KB
testcase_54 AC 176 ms
5,292 KB
testcase_55 AC 172 ms
5,040 KB
testcase_56 AC 175 ms
5,088 KB
testcase_57 AC 155 ms
5,008 KB
testcase_58 AC 165 ms
5,336 KB
testcase_59 AC 181 ms
5,856 KB
testcase_60 AC 171 ms
6,068 KB
testcase_61 AC 173 ms
5,800 KB
testcase_62 AC 156 ms
5,320 KB
testcase_63 AC 175 ms
5,092 KB
testcase_64 AC 173 ms
5,332 KB
testcase_65 AC 21 ms
4,336 KB
testcase_66 AC 22 ms
4,328 KB
testcase_67 AC 96 ms
5,056 KB
testcase_68 AC 99 ms
5,276 KB
testcase_69 AC 97 ms
4,332 KB
testcase_70 AC 108 ms
4,740 KB
testcase_71 AC 285 ms
4,332 KB
testcase_72 AC 301 ms
4,332 KB
testcase_73 AC 279 ms
4,804 KB
testcase_74 AC 303 ms
4,332 KB
testcase_75 AC 95 ms
4,336 KB
testcase_76 AC 105 ms
4,740 KB
testcase_77 AC 79 ms
4,332 KB
testcase_78 AC 87 ms
4,328 KB
testcase_79 AC 114 ms
4,332 KB
testcase_80 AC 114 ms
4,500 KB
testcase_81 AC 99 ms
4,332 KB
testcase_82 AC 88 ms
4,328 KB
testcase_83 AC 320 ms
4,380 KB
testcase_84 AC 343 ms
4,328 KB
testcase_85 AC 29 ms
4,328 KB
testcase_86 AC 34 ms
4,328 KB
testcase_87 AC 118 ms
8,512 KB
testcase_88 AC 108 ms
7,924 KB
testcase_89 AC 1 ms
4,332 KB
testcase_90 AC 1 ms
4,332 KB
testcase_91 AC 1 ms
4,328 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#[allow(unused_imports)]
use std::cmp::*;
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };
    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

// http://www.prefield.com/algorithm/container/avl_tree.html
// https://atcoder.jp/contests/ttpc2019/tasks/ttpc2019_h
// https://atcoder.jp/contests/ttpc2019/submissions/23366439
#[derive(Clone)]
struct Node {
    p: i64,
    sum: i64,
    size: usize,
    height: i32,
    ch: [Option<Box<Node>>; 2],
}

impl Node {
    fn new(p: i64) -> Self {
        Node {
            p: p,
            sum: p,
            size: 1,
            height: 1,
            ch: [None, None],
        }
    }
    // Insert a single element represented as a leaf node.
    fn insert(l: Option<Box<Node>>, x: Node) -> Option<Box<Node>> {
        let mut t = match l {
            None => return Some(Box::new(x)),
            Some(l) => l,
        };
        if t.p <= x.p {
            t.ch[0] = Node::insert(t.ch[0].take(), x);
        } else {
            t.ch[1] = Node::insert(t.ch[1].take(), x);
        }
        Node::cons(&mut t);
        Some(Node::balance(t))
    }
    fn erase(l: Option<Box<Node>>, p: i64) -> Option<Box<Node>> {
        let mut t = match l {
            None => return None,
            Some(l) => l,
        };
        if t.p == p {
            return Node::move_down(t.ch[0].take(), t.ch[1].take());
        }
        if t.p < p {
            t.ch[0] = Node::erase(t.ch[0].take(), p);
        } else {
            t.ch[1] = Node::erase(t.ch[1].take(), p);
        }
        Node::cons(&mut t);
        Some(Node::balance(t))
    }
    fn move_down(l: Option<Box<Node>>, r: Option<Box<Node>>) -> Option<Box<Node>> {
        let mut t = match l {
            None => return r,
            Some(l) => l
        };
        t.ch[1] = Node::move_down(t.ch[1].take(), r);
        Some(Node::balance(t))
    }
    fn len(t: &Option<Box<Node>>) -> usize {
        if let &Some(ref x) = t {
            x.size
        } else {
            0
        }
    }
    fn ht(t: &Option<Box<Node>>) -> i32 {
        if let &Some(ref x) = t {
            x.height
        } else {
            0
        }
    }
    fn sum(t: &Option<Box<Node>>) -> i64 {
        if let &Some(ref x) = t {
            x.sum
        } else {
            0
        }
    }
    fn at(l: &Option<Box<Node>>, pos: usize) -> Option<i64> {
        let t = match l {
            None => return None,
            Some(l) => l,
        };
        if pos >= t.size {
            return None;
        }
        let ll = Node::len(&t.ch[0]);
        if pos < ll {
            return Node::at(&t.ch[0], pos);
        }
        if pos == ll {
            return Some(t.p);
        }
        Node::at(&t.ch[1], pos - ll - 1)
    }
    fn acc(l: &Option<Box<Node>>, pos: usize) -> i64 {
        let t = match l {
            None => return 0,
            Some(l) => l,
        };
        if pos >= t.size {
            return t.sum;
        }
        let ll = Node::len(&t.ch[0]);
        if pos <= ll {
            return Node::acc(&t.ch[0], pos);
        }
        let ls = Node::sum(&t.ch[0]);
        ls + t.p + Node::acc(&t.ch[1], pos - ll - 1)
    }
    // Make t consistent.
    fn cons(t: &mut Box<Self>) {
        for i in 0..2 {
            if let &Some(ref c) = &t.ch[i] {
                assert!(if i == 0 { t.p <= c.p } else { t.p >= c.p }, "i = {}. t.p = {}, c.p = {}", i, t.p, c.p);
            }
        }
        t.height = std::cmp::max(Node::ht(&t.ch[0]), Node::ht(&t.ch[1])) + 1;
        t.size = 1 + Node::len(&t.ch[0]) + Node::len(&t.ch[1]);
        t.sum = t.p + Node::sum(&t.ch[0]) + Node::sum(&t.ch[1]);
    }
    fn rotate(mut t: Box<Self>, l: usize, r: usize) -> Box<Self> {
        let mut s = t.ch[r].take().unwrap();
        t.ch[r] = s.ch[l].take();
        Node::cons(&mut t);
        s.ch[l] = Some(Self::balance(t));
        Node::cons(&mut s);
        Self::balance(s)
    }
    fn balance(mut t: Box<Self>) -> Box<Self> {
        for i in 0..2 {
            if Self::ht(&t.ch[1 - i]) - Self::ht(&t.ch[i]) < -1 {
                let tmp = t.ch[i].as_mut().unwrap();
                if Self::ht(&tmp.ch[1 - i]) - Self::ht(&tmp.ch[i]) > 0 {
                    *tmp = 
                        Self::rotate(std::mem::replace(tmp, Box::new(Node::new(0))), i, 1 - i);
                }
                return Self::rotate(t, 1 - i , i);
            }
        }
        Node::cons(&mut t);
        t
    }
    fn each<F: FnMut(i64)>(t: &Option<Box<Self>>, f: &mut F) {
        let t = match t {
            None => return,
            Some(t) => t,
        };
        Node::each(&t.ch[0], f);
        f(t.p);
        Node::each(&t.ch[1], f);
    }
}

#[derive(Clone)]
struct AVLTree {
    root: Option<Box<Node>>,
}

impl AVLTree {
    fn new() -> Self {
        AVLTree { root: None }
    }
    #[allow(unused)]
    fn len(&self) -> usize {
        Node::len(&self.root)
    }
    fn insert(&mut self, p: i64) {
        self.root = Node::insert(self.root.take(), Node::new(p));
    }
    fn at(&self, pos: usize) -> Option<i64> {
        Node::at(&self.root, pos)
    }
    fn acc(&self, pos: usize) -> i64 {
        Node::acc(&self.root, pos)
    }
    fn erase(&mut self, p: i64) {
        self.root = Node::erase(self.root.take(), p);
    }
    // The order is not specified.
    #[allow(unused)]
    fn each<F: FnMut(i64)>(&self, mut f: F) {
        Node::each(&self.root, &mut f)
    }
}

fn solve() {
    let n;
    let k;
    let mut a;
    if true {
        input! {
            n_: usize,
            k_: usize,
            a_: [i64; n_],
        }
        n = n_;
        k = k_;
        a = a_;
    } else {
        n = 100000;
        k = 50000;
        a = vec![0; n];
        for i in 0 .. n {
            a[i] = i as i64 + 1;
        }
    }
    let mut acc = vec![0; n + 1];
    for i in 0..n {
        acc[i + 1] = acc[i] + a[i];
    }
    let mut ms = AVLTree::new();
    for i in 0..k {
        ms.insert(a[i]);
    }
    const INF: i64 = 1 << 50;
    let mut mi = INF;
    for i in k..n + 1 {
        let mid = (k + 1) / 2;
        let med = ms.at(mid - 1).unwrap();
        let sum = ms.acc(mid);
        let tmp = sum * 2 - acc[i] + acc[i - k] + med * (k as i64 - mid as i64 * 2);
        // eprintln!("{} => {} (med = {}, sum = {})", i, tmp, med, sum);
        // ms.each(|x| eprint!(" {}", x));
        // eprintln!();
        mi = min(mi, tmp);
        if i < n {
            ms.erase(a[i - k]);
            ms.insert(a[i]);
        }
    }
    println!("{}", mi);
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}
0