AtCoder Beginner Contest 442 D

https://atcoder.jp/contests/abc442/tasks/abc442_d

範囲の和を取るには累積和を計算しておけばよいですが、隣の入れ替えは累積和を一つ変えればいいだけなのでO(1)です。

// Swap and Range Sum
#![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()
}


//////////////////// Query ////////////////////

enum Query {
    Swap(usize),
    SumRange(usize, usize),
}

impl Query {
    fn read() -> Query {
        let v: Vec<usize> = read_vec();
        if v[0] == 1 {
            Query::Swap(v[1])
        }
        else {
            Query::SumRange(v[1], v[2])
        }
    }
}


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

fn read_input() -> (usize, Vec<i32>) {
    let v: Vec<usize> = read_vec();
    let Q = v[1];
    let A: Vec<i32> = read_vec();
    (Q, A)
}

fn accumulate(A: &Vec<i32>) -> Vec<i32> {
    let N = A.len();
    let mut acc: Vec<i32> = vec![0; N+1];
    for i in 0..N {
        acc[i+1] = acc[i] + A[i]
    }
    acc
}

fn swap(i: usize, acc: &mut Vec<i32>) {
    // A[i+1] = acc[i+2] - acc[i+1]
    acc[i+1] = acc[i] + acc[i+2] - acc[i+1]
}

fn print(first: usize, last: usize, acc: &Vec<i32>) {
    println!("{}", acc[last] - acc[first])
}

fn F(Q: usize, A: Vec<i32>) {
    let mut acc = accumulate(&A);
    for _ in 0..Q {
        match Query::read() {
            Query::Swap(x)        => swap(x-1, &mut acc),
            Query::SumRange(l, r) => print(l-1, r, &acc)
        }
    }
}

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