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) }