题意很好懂,就是一个长度为n的序列,s[i] 只可能是r,g,b,要你要满足就 j - i != k - j,并且s[i],s[j],s[k]两两不相同,并且i < j < k,的个数有多少个。
思路:
暴力O(n^3)模拟一遍铁超时,j - i != k - j 一开始一直在观察这个式子看能不能优化一下,事实上可以不管这个式子就一个区间[i,k]={B,R},那么我们在[i + 1,k - 1]这个区间找有多少个G就行了,需要考虑一下中点是否需要减掉,然后把所有的情况枚举出来就行了。这里用前缀和维护sum [ i ] [ 1 - 3 ]:表示从1到i有多少个R,B,G。
感觉写的有点点复杂了。。。。
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 10;
typedef long long int ll;
ll sum[maxn][4]; 
void solved(){
	ll n;cin>>n;
	char s[5000];scanf("%s",s + 1);
	ll r = 0, b = 0,g = 0;
	for(int i = 1; i <= n; i++){
		if(s[i] == 'R'){
			r++;
			sum[i][1] = sum[i - 1][1] + 1;
			sum[i][2] = sum[i - 1][2];
			sum[i][3] = sum[i - 1][3];
		}else if(s[i] == 'G'){
			g++;
			sum[i][1] = sum[i - 1][1];
			sum[i][2] = sum[i - 1][2] + 1;
			sum[i][3] = sum[i - 1][3];
		}else if(s[i] == 'B'){
			b++;
			sum[i][1] = sum[i - 1][1];
			sum[i][2] = sum[i - 1][2];
			sum[i][3] = sum[i - 1][3] + 1;
		}
	}
	//cout<<"r :"<<r<<" G:"<<g<<" B:"<<b<<endl;
	//cout<<"R: "<<sum[n][1]<<" G:"<<sum[n][2]<<" B:"<<sum[n][3]<<endl;
	ll ans = 0;
	for(int i = 1; i <= n; i++)
	for(int k = i + 1; k <= n; k++){
		if(s[i] == 'R' && s[k] == 'B' ){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'G')ans --;
			ans += sum[k - 1][2] - sum[i][2];
		}
		if(s[i] == 'B' && s[k] == 'R'){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'G')ans --;
			ans += sum[k - 1][2] - sum[i][2];
		}
		if(s[i] == 'G' && s[k] == 'B'){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'R')ans --;
			ans += sum[k - 1][1] - sum[i][1];
		}
		if(s[i] == 'B' && s[k] == 'G'){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'R')ans --;
			ans += sum[k - 1][1] - sum[i][1];
		}
		if(s[i] == 'R' && s[k] == 'G'){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'B')ans --;
			ans += sum[k - 1][3] - sum[i][3];
		}
		if(s[i] == 'G' && s[k] == 'R'){
			if((k - i + 1) & 1 && s[(i + k) /2] == 'B')ans --;
			ans += sum[k - 1][3] - sum[i][3];
		}
	}
	cout<<ans<<endl;
}
int main(){
	solved();
	return 0;
}