Buggy python submission (verdict: Time Limit Exceeded):
import bisect

def bs(x, key_func, arr):

	if len(arr) == 0 or arr == None:
		return -1

	n = len(arr)
	ini = 0
	fin = n - 1

	while ini < fin:
		m = (ini + fin) // 2
		if key_func(arr[m]) < x:
			ini = m + 1
		else:
			fin = m
	if fin == n - 1 and key_func(arr[fin]) < x:
		return n
	if key_func(arr[fin]) >= x:
		return max(0, fin - 1)
	return fin	

def main():
	N = int(input())	
	S = input()

	tb_i = {'BG': [], 'BR': [], 'GR': []}
	for i in range(N):
		for j in range(i + 1, N):
			if S[i] == S[j]:
				continue
			word = ''.join(list(sorted([S[i], S[j]])))
			tb_i[word].append((j, j - i))
	
	for key in tb_i:
		tb_i[key].sort(key=lambda x: x[0])
	
	rs = 0	
	for i in range(2, N):	
		word = None
		if S[i] == 'R':
			word = 'BG'
		if S[i] == 'G':
			word = 'BR'
		if S[i] == 'B':
			word = 'GR'

		idx = bs(i, lambda x: x[0], tb_i[word])
		if idx == len(tb_i[word]):
			idx -= 1	
		if idx == 0 and tb_i[word][0][0] >= i:
			idx -= 1
		for j in range(idx, -1, -1):
			if tb_i[word][j][1] == i - tb_i[word][j][0]:
				continue
			rs += 1
	print(rs)
	return 0 

main()


Fixed submission:
import bisect

def main():
	N = int(input())	
	S = input()

	tb_pos = {'BG': None, 'BR': None, 'GR': None}
	for k in tb_pos:
		tb_pos[k] = [0] * (N + 1)
	
	rs = 0
	for i in range(N):
		for j in range(i + 1, N):
			if S[i] == S[j]:
				continue
			d = j - i
			c1, c2 = S[i], S[j]
			if c1 > c2:
				c1, c2 = c2, c1
			word = c1 + c2
			if j + d < N and S[j + d] not in word:
				rs -= 1
			tb_pos[word][j + 1] += 1 

	for i in range(1, N + 1):
		for k in tb_pos:
			tb_pos[k][i] += tb_pos[k][i - 1]
				
	for j in range(2, N):
		word = None
		if S[j] == 'B':
			word = 'GR'
		elif S[j] == 'G':
			word = 'BR'
		else:
			word = 'BG'
		
		rs += tb_pos[word][j + 1]

	print(rs)
	return 0 

main()

Buggy python submission (verdict: Time Limit Exceeded):
import bisect

def bs(x, key_func, arr):

	if len(arr) == 0 or arr == None:
		return -1

	n = len(arr)
	ini = 0
	fin = n - 1

	while ini < fin:
		m = (ini + fin) // 2
		if key_func(arr[m]) < x:
			ini = m + 1
		else:
			fin = m
	if fin == n - 1 and key_func(arr[fin]) < x:
		return n
	if key_func(arr[fin]) >= x:
		return max(0, fin - 1)
	return fin	

def main():
	N = int(input())	
	S = input()

	tb_i = {'BG': [], 'BR': [], 'GR': []}
	for i in range(N):
		for j in range(i + 1, N):
			if S[i] == S[j]:
				continue
			word = ''.join(list(sorted([S[i], S[j]])))
			tb_i[word].append((j, j - i))
	
	for key in tb_i:
		tb_i[key] = list(sorted(tb_i[key], key=lambda x: x[0]))
	
	rs = 0	
	for i in range(2, N):	
		word = None
		if S[i] == 'R':
			word = 'BG'
		if S[i] == 'G':
			word = 'BR'
		if S[i] == 'B':
			word = 'GR'

		idx = bs(i, lambda x: x[0], tb_i[word])
		if idx == len(tb_i[word]):
			idx -= 1	
		if idx == 0 and tb_i[word][0][0] >= i:
			idx -= 1
		for j in range(idx, -1, -1):
			if tb_i[word][j][1] == i - tb_i[word][j][0]:
				continue
			rs += 1
	print(rs)
	return 0 

main()


Fixed submission:
import bisect

def main():
	N = int(input())	
	S = input()

	tb_pos = {'BG': None, 'BR': None, 'GR': None}
	for k in tb_pos:
		tb_pos[k] = [0] * (N + 1)
	
	rs = 0
	for i in range(N):
		for j in range(i + 1, N):
			if S[i] == S[j]:
				continue
			d = j - i
			c1, c2 = S[i], S[j]
			if c1 > c2:
				c1, c2 = c2, c1
			word = c1 + c2
			if j + d < N and S[j + d] not in word:
				rs -= 1
			tb_pos[word][j + 1] += 1 

	for i in range(1, N + 1):
		for k in tb_pos:
			tb_pos[k][i] += tb_pos[k][i - 1]
				
	for j in range(2, N):
		word = None
		if S[j] == 'B':
			word = 'GR'
		elif S[j] == 'G':
			word = 'BR'
		else:
			word = 'BG'
		
		rs += tb_pos[word][j + 1]

	print(rs)
	return 0 

main()