Problem:
Score : 400 points

Problem Statement

We have an undirected graph G with N vertices numbered 1 to N and N edges as follows:

For each i=1,2,...,N-1, there is an edge between Vertex i and Vertex i+1.

There is an edge between Vertex X and Vertex Y.

For each k=1,2,...,N-1, solve the problem below:

Find the number of pairs of integers (i,j) (1 \leq i < j \leq N) such that the shortest distance between Vertex i and Vertex j in G is k.

Constraints

3 \leq N \leq 2 \times 10^3

1 \leq X,Y \leq N

X+1 < Y

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N X Y

Output

For each k=1, 2, ..., N-1 in this order, print a line containing the answer to the problem.

Sample Input 1

5 2 4

Sample Output 1

5
4
1
0

The graph in this input is as follows:

There are five pairs (i,j) (1 \leq i < j \leq N) such that the shortest distance between Vertex i and Vertex j is 1: (1,2)\,,(2,3)\,,(2,4)\,,(3,4)\,,(4,5).

There are four pairs (i,j) (1 \leq i < j \leq N) such that the shortest distance between Vertex i and Vertex j is 2: (1,3)\,,(1,4)\,,(2,5)\,,(3,5).

There is one pair (i,j) (1 \leq i < j \leq N) such that the shortest distance between Vertex i and Vertex j is 3: (1,5).

There are no pairs (i,j) (1 \leq i < j \leq N) such that the shortest distance between Vertex i and Vertex j is 4.

Sample Input 2

3 1 3

Sample Output 2

3
0

The graph in this input is as follows:

Sample Input 3

7 3 7

Sample Output 3

7
8
4
2
0
0

Sample Input 4

10 4 8

Sample Output 4

10
12
10
8
4
1
0
0
0

Solution in Rust (1.15.1) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
#![allow(unused_imports)]
#![allow(clippy::many_single_char_names)]
#![allow(clippy::suspicious_arithmetic_impl)]

// using Rust(1.42.0)
// My Library Repo is at "https://github.com/Loptall/prcn_lib"
// check available crates on AtCoder at "https://atcoder.jp/contests/language-test-202001"

/*
    AtCoder Language Update 2020204 お疲れ様でした! 有難いです(p.s. 過去問対応もありがとうございます)
*/

// from std...
use std::cmp::{
    max, min,
    Ordering::{Equal, Greater, Less},
};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::mem::swap;
use std::ops::*;
use std::usize::{MAX, MIN};
use std::{i128, i16, i32, i64, i8, isize, u128, u16, u32, u64, u8, usize};

// Dep crates are...
use itertools::*;
use itertools_num::*;
use lazy_static::lazy_static;
use maplit::{btreemap, btreeset, hashmap, hashset};
use num_bigint::{BigInt, BigUint};
use num_complex::Complex;
use num_integer::{binomial, gcd, lcm, Integer};
use num_rational::Rational;
use num_traits::{One, Zero};
use permutohedron::Heap;
use petgraph::unionfind::UnionFind;
use proconio::{fastout, input, is_stdin_empty, marker::*};
use rand::random;

// code...
// #[fastout]
fn main() {
    input! {
        n: usize, x: usize, y: usize
    }

    let mut edges = (0..n-1).map(|x| (x, x + 1)).collect::<Vec<_>>();
    edges.push((x-1, y-1));
    let g = make_undirected_graph(n, &edges);

    let mut c = Vec::new();
    for s in 0..n {
        let mut d = dist_table(&g, s);
        c.append(&mut d);
    }

    let ans = unique_count(&c);
    for k in 1..n {
        println!("{}", ans.get(&k).unwrap_or(&0) / 2);
    }
}

/// 配列に含まれる要素(T: Ord + Copy)別にその個数を数えて
/// `BTreeMap<T, usize>`の形にして返す
pub fn unique_count<T: Ord + Copy>(v: &[T]) -> BTreeMap<T, usize> {
    let mut map = BTreeMap::new();
    for e in v {
        let h = map.entry(*e).or_insert(0);
        *h += 1;
    }
    map
}


/// 重みなし有向グラフ
pub fn make_directed_graph(n: usize, edges: &[(usize, usize)]) -> UnweightedGraph {
    let mut g = vec![vec![]; n];
    for &(u, v) in edges.iter() {
        g[u].push(v);
    }
    g
}

/// 重みなし無向グラフ
pub fn make_undirected_graph(n: usize, edges: &[(usize, usize)]) -> UnweightedGraph {
    let mut g = vec![vec![]; n];
    for &(u, v) in edges.iter() {
        g[u].push(v);
        g[v].push(u);
    }
    g
}

/// 重み付き有向グラフ
pub fn make_weighted_directed_graph<W: Clone>(
    n: usize,
    edges: &[(usize, usize, W)],
) -> WeightedVertexGraph<W> {
    let mut g = vec![vec![]; n];
    for &(u, v, ref w) in edges.iter() {
        g[u].push((v, w.clone()));
    }
    g
}

/// 重み付き無向グラフ
pub fn make_weighted_undirected_graph<W: Clone>(
    n: usize,
    edges: &[(usize, usize, W)],
) -> WeightedVertexGraph<W> {
    let mut g = vec![vec![]; n];
    for &(u, v, ref w) in edges.iter() {
        g[u].push((v, w.clone()));
        g[v].push((u, w.clone()));
    }
    g
}



pub trait Graph<'a> {
    type NodeId: Copy;
    type Iter: Iterator<Item = Self::NodeId>;
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool;
    fn index(&self, a: Self::NodeId) -> usize;
    fn neighbors(&'a self, a: Self::NodeId) -> Self::Iter;
}

/// 重みなしグラフ
pub type UnweightedGraph = Vec<Vec<usize>>;

impl<'a> Graph<'a> for UnweightedGraph {
    type NodeId = usize;
    type Iter = std::iter::Cloned<std::slice::Iter<'a, Self::NodeId>>;

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.len() == 0
    }

    fn index(&self, a: Self::NodeId) -> usize {
        a
    }

    fn neighbors(&'a self, a: Self::NodeId) -> Self::Iter {
        self[a].iter().cloned()
    }
}

/// 重みありグラフ
pub type WeightedVertexGraph<W> = Vec<Vec<(usize, W)>>;

impl<'a, W> Graph<'a> for WeightedVertexGraph<W>
where
    W: std::marker::Copy + Clone + 'a,
{
    type NodeId = (usize, W);
    type Iter = std::iter::Cloned<std::slice::Iter<'a, Self::NodeId>>;

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.len() == 0
    }

    fn index(&self, a: Self::NodeId) -> usize {
        a.0
    }

    fn neighbors(&'a self, a: Self::NodeId) -> Self::Iter {
        self[a.0].iter().cloned()
    }
}

// /// Returns a vector which stores distances from `start`.
// /// For unreachable node, `usize::MAX` is stored.
// pub fn make_dist_table<'a, G: Graph<'a, NodeId = usize>>(g: &'a G, start: G::NodeId) -> Vec<usize> {
//     let mut dist = vec![std::usize::MAX; g.len()];
//     dist[start] = 0;
//     for (u, v) in bfs(g, start) {
//         dist[v] = dist[u] + 1;
//     }
//     dist
// }

pub struct Bfs<'a, G: Graph<'a>> {
    visited: Vec<bool>,
    q: VecDeque<(G::NodeId, Option<G::NodeId>)>,
    g: &'a G,
}

impl<'a, G: Graph<'a>> Iterator for Bfs<'a, G> {
    type Item = (G::NodeId, G::NodeId);
    fn next(&mut self) -> Option<Self::Item> {
        if let Some((u, prev)) = self.q.pop_front() {
            for v in self.g.neighbors(u) {
                if !self.visited[self.g.index(v)] {
                    self.visited[self.g.index(v)] = true;
                    self.q.push_back((v, Some(u)));
                }
            }

            if let Some(prev) = prev {
                Some((prev, u))
            } else {
                self.next()
            }
        } else {
            None
        }
    }
}

/// `start`の頂点からの幅優先探索時の、
/// 頂点から頂点の接続をイテレートするIteratorを作る
///
/// ```
/// let e = &[(0, 2), (0, 1), (1, 2), (2, 3), (3, 4), (3, 5), (1, 5)];
///
/// let g = make_undirected_graph(6, e);
///
/// for (f, t) in bfs(&g, 0) {
///     println!("{} -> {}", f, t);
/// }
/// ```
///
/// これは
///
/// `0 -> 2`
///
/// `0 -> 1`
///
/// `2 -> 3`
///
/// `1 -> 5`
///
/// `3 -> 4`
///
/// を表示する
pub fn bfs<'a, G>(g: &'a G, start: G::NodeId) -> Bfs<'a, G>
where
    G: Graph<'a, NodeId = usize>,
{
    let n = g.len();
    let mut visited = vec![false; n];
    let mut q = VecDeque::new();
    visited[start] = true;
    q.push_back((start, None));

    Bfs { visited, q, g }
}


/// 重みなしグラフにおいて、幅優先探索を用いて任意の頂点から、各頂点への最短距離を求める
///
/// dist[i] = (startからiまでの最短距離)
pub fn dist_table<'a, G>(g: &'a G, start: G::NodeId) -> Vec<usize>
where
    G: Graph<'a, NodeId = usize>,
{
    let mut dist = vec![std::usize::MAX; g.len()];
    dist[start] = 0;
    for (f, t) in bfs(g, start) {
        dist[t] = dist[f] + 1;
    }
    dist
}

/// 重みなしグラフでの2頂点の最短距離を幅優先探索で求める
///
/// goalまでの経路が見つかった時点で探索を打ち切るので、
/// グラフのサイズの大きさに直接の影響を受けないことが期待される
pub fn shortest_path<'a, G: Graph<'a, NodeId = usize>>(
    g: &'a G,
    start: usize,
    goal: usize,
) -> usize {
    let mut dist = vec![std::usize::MAX; g.len()];
    dist[start] = 0;
    for (f, t) in bfs(g, start) {
        if t == goal {
            return dist[f] + 1;
        }
        dist[t] = dist[f] + 1;
    }

    std::usize::MAX
}

/// グラフを連結成分ごとに分解する。
/// 返り値`r`は、`r[c][i] = 頂点iはグループcに属する`
pub fn classify_into_connected_group<'a, G: Graph<'a, NodeId = usize>>(
    g: &'a G,
) -> Vec<Vec<usize>> {
    let mut classified = vec![None; g.len()];
    let mut cur = 0usize;
    for u in 0..g.len() {
        match classified[u] {
            Some(_) => {}
            None => {
                for (i, _) in dist_table(g, u)
                    .iter()
                    .enumerate()
                    .filter(|x| *x.1 != std::usize::MAX)
                {
                    classified[i] = Some(cur);
                }
                cur += 1;
            }
        }
    }

    let mut res = vec![Vec::new(); cur];
    for (i, c) in classified.into_iter().map(|x| x.unwrap()).enumerate() {
        res[c].push(i);
    }

    res
}
*/

fn main() {
    let exe = "/tmp/binB30422FE";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";