题意:一个人是按数据给出的顺序出石头剪刀布,一个人是先出X个石头,Y个布,Z个剪刀
用前缀和来维护R,P,S数组,R[i]表示前i个中有多少个R
cnt1用来统计能打赢的,cnt2统计平手的次数
因为一个区间分成了3段,那么有两个节点,枚举中间两个节点即可
然后看那3段中分别有多少个能打赢的,和能打成平手的,统计一下满足条件的次数,就是答案了
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MX = 200000 + 5;
const int INF = 0x3f3f3f3f;
char line[MX];
int R[MX], P[MX], S[MX];
int main() {
//freopen("input.txt","r",stdin);
int T, L;
scanf("%d", &T);
while(T--) {
memset(R, 0, sizeof(R));
memset(P, 0, sizeof(P));
memset(S, 0, sizeof(S));
scanf("%d%s", &L, line + 1);
for(int i = 1; i <= L; i++) {
R[i] = R[i - 1];
P[i] = P[i - 1];
S[i] = S[i - 1];
if(line[i] == 'R') R[i]++;
if(line[i] == 'P') P[i]++;
if(line[i] == 'S') S[i]++;
}
int ans = 0;
for(int i = 0; i <= L; i++) {
for(int j = i; j <= L; j++) {
int cnt1 = S[i], cnt2 = R[i];
if(j >= i) cnt1 += R[j] - R[i], cnt2 += P[j] - P[i];
if(L >= j) cnt1 += P[L] - P[j], cnt2 += S[L] - S[j];
if(cnt1 > L - cnt1 - cnt2) {
ans++;
}
}
}
printf("%d\n", ans);
}
return 0;
}