Problem:
Score : 400 points

Problem Statement

We have a string S of length N consisting of R, G, and B.

Find the number of triples (i,~j,~k)~(1 \leq i < j < k \leq N) that satisfy both of the following conditions:

S_i \neq S_j, S_i \neq S_k, and S_j \neq S_k.

j - i \neq k - j.

Constraints

1 \leq N \leq 4000

S is a string of length N consisting of R, G, and B.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of triplets in question.

Sample Input 1

4
RRGB

Sample Output 1

1

Only the triplet (1,~3,~4) satisfies both conditions. The triplet (2,~3,~4) satisfies the first condition but not the second, so it does not count.

Sample Input 2

39
RBRBGRBGGBBRRGBBRRRBGGBRBGBRBGBRBBBGBBB

Sample Output 2

1800

Solution in Kotlin (1.3.71) (judge verdict: Accepted)

fun main(arg: Array<String>) {
    val (R, G, B) = listOf(0, 1, 2)
    val N = nextInt()
    val S = next()
    val A = S.map {
        when(it) {
            'R' -> 0
            'G' -> 1
            'B' -> 2
            else -> 999
        } }
    val RGB = Array(3) { IntArray(N) }
    A.forEachIndexed { index, ch -> RGB[ch][index] = 1 }
    for (m in 0 until 3)
        for (n in (1 until N).reversed()) RGB[m][n - 1] += RGB[m][n]
    fun get(c: Int, n: Int, m: Int): Int {
        var p = RGB[c][m + 1]
        if (p > 0 && m + (m - n) < N && c == A[m + (m - n)]) p -= 1
        return p
    }
    var ans = 0L
    for (n in 0 until N - 2) {
        when (A[n]) {
            R -> {
                for (m in n + 1 until N - 1) {
                    when (A[m]) {
                        G -> ans += get(B, n, m)
                        B -> ans += get(G, n, m)
                        else -> { }
                    }
                }
            }
            G -> {
                for (m in n + 1 until N - 1) {
                    when (A[m]) {
                        R -> ans += get(B, n, m)
                        B -> ans += get(R, n, m)
                        else -> { }
                    }
                }
            }
            B -> {
                for (m in n + 1 until N - 1) {
                    when (A[m]) {
                        R -> ans += get(G, n, m)
                        G -> ans += get(R, n, m)
                        else -> { }
                    }
                }
            }
        }
    }
    return println(ans)
}

fun next() = readLine()!!
fun nextInt(offset: Int = 0) = Integer.parseInt(next()) + offset
fun nextLong() = next().toLong()
fun nextDouble() = next().toDouble()
fun listOfString() = next().split(" ")
fun listOfInt() = listOfString().map(String::toInt)
fun listOfLong() = listOfString().map(String::toLong)
fun listOfDouble() = listOfString().map(String::toDouble)
fun listOfInt(offset: Int = 0) = listOfString().map { Integer.parseInt(it) + offset }
fun listOfInt(vararg offset: Int) = listOfString().map { Integer.parseInt(it) }.mapIndexed { index, int -> int + offset[index % offset.size] }
fun listOfLong(offset: Long = 0L) = listOfString().map { java.lang.Long.parseLong(it) + offset }
fun listOfLong(vararg offset: Long) = listOfString().map { java.lang.Long.parseLong(it) }.mapIndexed { index, long -> long + offset[index % offset.size] }
fun listOfDouble(offset: Double = 0.0) = listOfString().map { java.lang.Double.parseDouble(it) + offset }
fun pairIntLong() = listOfLong().let { Pair(it[0].toInt(), it[1]) }
fun tripleIntIntLong() = listOfLong().let { Triple(it[0].toInt(), it[1].toInt(), it[2]) }
fun tripleIntLongLong() = listOfLong().let { Triple(it[0].toInt(), it[1], it[2]) }
fun pairIntLong(offset: Pair<Int, Long> = Pair(0, 0L)) = listOfLong().let { Pair(it[0].toInt() + offset.first, it[1] + offset.second) }
fun tripleIntIntLong(offset: Triple<Int, Int, Long> = Triple(0, 0, 0L)) = listOfLong().let { Triple(it[0].toInt() + offset.first, it[1].toInt() + offset.second, it[2] + offset.third) }
fun tripleIntLongLong(offset: Triple<Int, Long, Long> = Triple(0, 0L, 0L)) = listOfLong().let { Triple(it[0].toInt() + offset.first, it[1] + offset.second, it[2] + offset.third) }