思路:第一眼看是线段树,于是搞了一发,t在61,不过还能优化,方法想到了,代码实现不会,还是菜。
看学长并查集180ms搞过,遂学之。
具体方法是将访问过的放到一个并查集里,祖先一直指向没访问过的那个元素。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
#define R 0
#define B 1
#define G 2
char s[N];
int fa[N], n, m, l, r, cnt[3];
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main() {
for(int i = 0; i < N; ++i)
fa[i] = i;
scanf("%d%d%s", &n, &m, s + 1);
for(int i = 1; i <= n; ++i) {
if(s[i] == 'R')
cnt[R]++;
if(s[i] == 'B')
cnt[B]++;
if(s[i] == 'G')
cnt[G]++;
}
while(m--) {
scanf("%d%d", &l, &r);
for(int i = find(l); i <= r; i = find(i)) {
if(s[i] == 'R')
cnt[R]--, cnt[B]++;
if(s[i] == 'G')
cnt[G]--, cnt[R]++;
if(s[i] == 'B')
cnt[B]--, cnt[G]++;
fa[i] = i + 1;
}
printf("%d %d %d\n", cnt[R], cnt[G], cnt[B]);
}
}