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 Kotlin (1.0.0) (judge verdict: Time Limit Exceeded)


import java.util.*

fun main(args: Array<String>) = ABC160D.main()

object ABC160D {
    fun log(message: Any?) {
        //println(message)// TODO: ←消す
    }

    val graph: WeightedGraph<NumNode>
    val nodes: List<NumNode>
    val N: Int

    init {
        val (n, x, y) = readInts()
        N = n
        nodes = (1..n).map { NumNode(it) }
        val edges1 = (
                (1..n - 1).map { nodes[it - 1] to nodes[it] } + listOf(nodes[x - 1] to nodes[y - 1])
                ).associate { it to 1 }
        val edges = edges1 + edges1.mapKeys { it.key.second to it.key.first }
        log(edges.keys.joinToString("\n"))
        graph = WeightedGraph(edges)
    }

    fun main() {
        val combination = Combination<NumNode>().generate(nodes, 2)

        val distBucket = (1..N - 1).map { 0 }.toMutableList()   // k->個数

        val dists = combination.map {
            val i = it.first()
            val j = it.last()
            val d = dist(i, j)
            if (distBucket[d-1] != null) distBucket[d-1] = distBucket[d-1] + 1
            d
        }.toList()

        println(distBucket.joinToString("\n"))

    }

    fun dist(i: NumNode, j: NumNode): Int { // i,j: 1-origin
        val search = DijkstraSearch(
            start = i,
            goal = j,
            graph = graph
        )
        val d = search.searchPathAndCost()!!.second
        log("$i->$j: $d")
        return d
    }

    data class NumNode(val n: Int) : Node {
        override fun neighbors(): Sequence<Node> = graph.neighbors[this]!!.asSequence()

        override fun toString(): String = n.toString()
    }

    /*####################################################################################*/

    fun readInts() = readLine()!!.split(" ").map { it.toInt() }

    class Combination<T> : BasicCombinator<T>() {
        override fun List<T>.chooseRemains(i: Int): List<T> = this.drop(i + 1)
    }

    abstract class BasicCombinator<T> {
        abstract fun List<T>.chooseRemains(i: Int): List<T>

        fun generate(items: List<T>, k: Int): Sequence<List<T>> {
            when {
                (k < 0) ->
                    throw IllegalArgumentException()
                (k == 0) ->
                    return emptySequence()
                (k == 1) ->
                    return items.asSequence().map { listOf(it) }
                else ->
                    return items.asSequence().mapIndexed { index, first ->
                        val remains = items.chooseRemains(index)
                        generate(remains, k - 1).map { first + it }
                    }.flatten()
            }
        }

        private operator fun T.plus(other: List<T>): List<T> {
            val list = mutableListOf(this)
            list.addAll(other)
            return list
        }
    }

    interface Node {
        fun neighbors(): Sequence<Node>
    }

    class WeightedGraph<T : Node>(
        weightedEdges: Map<Pair<T, T>, Int>
    ) {
        val nodes: Set<T> = weightedEdges.keys.flatMap { it.toList() }.distinct().toSet()
        val weights: Map<Pair<T, T>, Int> = weightedEdges
        val neighbors: Map<T, Set<T>> =
            weights.keys.groupBy { it.first }.mapValues { e -> e.value.map { it.second }.toSet() }

        fun neighborsOf(node: T): Sequence<T> {
            return neighbors[node]?.asSequence() ?: emptySequence()
        }
    }

    class DijkstraSearch<T : Node>(
        val start: T,
        val goal: T,
        val graph: WeightedGraph<T>
    ) {
        fun searchPathAndCost(): Pair<List<T>, Int>? {
            val weight = graph.weights

            var goalState: Pair<List<T>, Int>? = null
            val costMemo: MutableMap<T, Int> = HashMap(graph.neighbors.size)
            costMemo[start] = 0
            val search = BreadthFirstSearch(
                root = start,
                initialState = (emptyList<T>() to 0),
                shouldVisit = { from, to, state ->
                    val prevCost = costMemo[to] ?: Int.MAX_VALUE
                    val newCost = weight[from to to]?.plus(state.second) ?: Int.MAX_VALUE
                    val shouldVisit = (from != goal) && (newCost < prevCost)
                    if (shouldVisit) costMemo[to] = newCost
                    shouldVisit
                },
                whenVisit = { from, to, state ->
                    val newState = state.first + to to costMemo[to]!!
                    if (to == goal) goalState = newState
                    newState
                })
            search.traverse()
            return goalState
        }
    }

    class BreadthFirstSearch<T : Node, S>(
        root: T,
        initialState: S,
        whenVisit: (from: T?, to: T, state: S) -> S = { f, t, s -> s },
        shouldVisit: (from: T, to: T, state: S) -> Boolean
    ) : SearchBase<T, S>(root, initialState, whenVisit, shouldVisit) {
        private val stack = LinkedList<Pair<T, S>>()
        override fun queue(p: Pair<T, S>) {
            stack.addLast(p)
        }

        override fun pop(): Pair<T, S>? {
            val first = stack.firstOrNull()
            if (first != null) stack.removeFirst()
            return first
        }
    }

    interface Search<T : Node> {
        fun traverseSequence(): Sequence<T>
        fun traverse(): Unit = traverseSequence().forEach { }
    }

    abstract class SearchBase<T : Node, S>(
        private val root: T,
        private val initialState: S,
        private val whenVisit: (from: T?, to: T, state: S) -> S = { f, t, s -> s },
        private val shouldVisit: (from: T, to: T, state: S) -> Boolean
    ) : Search<T> {
        abstract fun queue(p: Pair<T, S>)
        abstract fun pop(): Pair<T, S>?

        override fun traverseSequence(): Sequence<T> {
            val state = whenVisit(null, root, initialState)
            queue(root to state)
            return searchAll()
        }

        private fun searchAll(): Sequence<T> = generateSequence {
            pop()?.let { p ->
                val first = p.first
                val state = p.second
                first.neighbors().filter {
                    shouldVisit(first, it as T, state)
                }.forEach {
                    val newState = whenVisit(first, it as T, state)
                    queue(it to newState)
                }
                first
            }
        }
    }
}