競プロ典型 010

https://atcoder.jp/contests/typical90/tasks/typical90_j

範囲の和をクエリを処理するのに、累積を計算しておいて差を取るという典型的な問題ですね。

// Score Sum Queries
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}


//////////////////// process ////////////////////

type Student = (i32, i64);

fn read_student() -> Student {
    let v: Vec<i64> = read_vec();
    let C: i32 = v[0] as i32;
    let P = v[1];
    (C, P)
}

fn read_input() -> (Vec<Student>, usize) {
    let N: usize = read();
    let students: Vec<Student> = (0..N).map(|_| read_student()).collect();
    let Q: usize = read();
    (students, Q)
}

fn accumulate(students: Vec<Student>) -> Vec<(i64, i64)> {
    let N = students.len();
    let mut acc: Vec<(i64, i64)> = vec![(0, 0); N+1];
    for (i, (C, P)) in students.into_iter().enumerate() {
        acc[i+1] = 
            if C == 1 {
                (acc[i].0 + P, acc[i].1)
            }
            else {
                (acc[i].0, acc[i].1 + P)
            };
    }
    acc
}

fn read_query() -> (usize, usize) {
    let v = read_vec();
    let (L, R) = (v[0], v[1]);
    (L, R)
}

fn F(students: Vec<Student>, Q: usize) {
    let acc = accumulate(students);
    for _ in 0..Q {
        let (L, R) = read_query();
        let n1 = acc[R].0 - acc[L-1].0;
        let n2 = acc[R].1 - acc[L-1].1;
        println!("{} {}", n1, n2)
    }
}

fn main() {
    let (students, Q) = read_input();
    F(students, Q)
}