线段树区间合并,合并注意下r, b的转移即可
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 50005;
int t, n, q;
char s[3], str[N];
#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
struct Node {
int l, r, lw, lb, lbw, rw, rb, rwb, wbw;
} node[N * 4];
Node gao(Node a, Node b) {
Node ans;
ans.l = a.l; ans.r = b.r;
ans.wbw = a.wbw + b.wbw;
ans.lbw = a.lbw;
ans.lw = a.lw;
ans.lb = a.lb;
ans.rwb = b.rwb;
ans.rw = b.rw;
ans.rb = b.rb;
ans.wbw += min(a.rw, b.lbw);
ans.wbw += min(a.rwb, b.lw);
if (a.l == a.r) ans.lbw = min(a.lb, b.rw);
if (b.l == b.r) ans.rwb = min(a.rw, b.lb);
return ans;
}
void pushup(int x) {
node[x] = gao(node[lson(x)], node[rson(x)]);
}
void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r;
if (l == r) {
node[x].lw = node[x].lb = node[x].lbw = node[x].wbw = 0;
node[x].rw = node[x].rb = node[x].rwb = 0;
if (str[l] == 'b') node[x].lb = node[x].rb = 1;
else node[x].lw = node[x].rw = 1;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
}
void add(int v, char c, int x = 0) {
if (node[x].l == node[x].r) {
node[x].lb = node[x].rb = node[x].lw = node[x].rw = 0;
if (c == 'b') node[x].lb = node[x].rb = 1;
else node[x].lw = node[x].rw = 1;
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (v <= mid) add(v, c, lson(x));
else add(v, c, rson(x));
pushup(x);
}
Node query(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r)
return node[x];
int mid = (node[x].l + node[x].r) / 2;
if (l <= mid && r > mid) return gao(query(l, r, lson(x)), query(l, r, rson(x)));
else if (l <= mid) return query(l, r, lson(x));
else if (r > mid) return query(l, r, rson(x));
}
int main() {
scanf("%d", &t);
int cas = 0;
while (t--) {
scanf("%d%d", &n, &q);
scanf("%s", str);
build(0, n - 1);
int tp, l, r, v;
printf("Case %d:\n", ++cas);
while (q--) {
scanf("%d", &tp);
if (tp == 0) {
scanf("%d%d", &l, &r);
printf("%d\n", query(l, r).wbw);
} else {
scanf("%d%s", &v, s);
add(v, s[0]);
}
}
}
return 0;
}