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 C# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;

namespace Atcoder_0404
{
    class Program
    {
        static void Main(string[] args)
        {
            var num = GetInput_int()[0];
            string datas = GetInput_string()[0];
            List<int> _Rindex = new List<int>();
            List<int> _Gindex = new List<int>();
            List<int> _Bindex = new List<int>();

            for (int i = 0; i < num; i++)
            {
                switch (datas[i])
                {
                    case 'R':
                        _Rindex.Add(i);
                        break;
                    case 'G':
                        _Gindex.Add(i);
                        break;
                    case 'B':
                        _Bindex.Add(i);
                        break;
                }
            }
            int sum = 0;
            for (int i = 0; i < num; i++)
            {
                bool r1 = false;
                bool g1 = false;
                bool b1 = false;
                switch (datas[i])
                {
                    case 'R':
                        r1 = true;
                        break;
                    case 'G':
                        g1 = true;
                        break;
                    case 'B':
                        b1 = true;
                        break;
                }
                int fromIndexR = 0;
                int fromIndexG = 0;
                int fromIndexB = 0;
                for (int j = i + 1; j < num; j++)
                {
                    bool r2 = false;
                    bool g2 = false;
                    bool b2 = false;
                    switch (datas[j])
                    {
                        case 'R':
                            if (r1) continue;
                            r2 = true;
                            break;
                        case 'G':
                            if (g1) continue;
                            g2 = true;
                            break;
                        case 'B':
                            if (b1) continue;
                            b2 = true;
                            break;
                    }
                    int dif = j - i;
                    int target = j + dif;
                    int add = 0;
                    if ((r1 && b2) || (b1 && r2))
                    {
                        for (int k = fromIndexG; k < _Gindex.Count; k++)
                        {
                            if (j < _Gindex[k])
                            {
                                add = _Gindex.Count - k;
                                if (add > 0 && _Gindex.Contains(target)) sum -= 1;
                                fromIndexG = k;
                                break;
                            }
                        }
                    }
                    else if ((r1 && g2) || (r2 && g1))
                    {

                        for (int k = fromIndexB; k < _Bindex.Count; k++)
                        {
                            if (j < _Bindex[k])
                            {
                                add = _Bindex.Count - k;
                                if (add > 0 && _Bindex.Contains(target)) sum -= 1;
                                fromIndexB = k;
                                break;
                            }
                        }
                    }
                    else if ((b1 && g2) || (b2 && g1))
                    {
                        for (int k = fromIndexR; k < _Rindex.Count; k++)
                        {
                            if (j < _Rindex[k])
                            {
                                add = _Rindex.Count - k;
                                if (add > 0 && _Rindex.Contains(target)) sum -= 1;
                                fromIndexR = k;
                                break;
                            }
                        }
                    }
                    sum += add;
                }
            }
            Console.WriteLine(sum);
            //GetInput_string();
        }
        #region input
        

        static string[] GetInput_string()
        {
            var input = Console.ReadLine().Split(' ');
            return input;
        }

        static int[] GetInput_int()
        {
            var input = GetInput_string();
            var result = new int[input.Length];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = int.Parse(input[i]);
            }
            return result;
        }
        static long[] GetInput_long()
        {
            var input = GetInput_string();
            var result = new long[input.Length];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = long.Parse(input[i]);
            }
            return result;
        }
        #endregion
        #region sonota
        static void Swap_array<T>(T[] target, int a, int b)
        {
            T temp = target[a];
            target[a] = target[b];
            target[b] = temp;
        }
        static void Swap_list<T>(List<T> target, int a, int b)
        {
            T temp = target[a];
            target[a] = target[b];
            target[b] = temp;
        }
        #endregion
    }
}