题意:
两个操作,改变区间某个位置的值,询问区间好友wbw串的个数。
题解:
将线段树的每个点的值设为以这个点为结尾的串是否是wbw。接下来就是裸的线段树。注意一个位置改变会影响三个位置,所以要更新三个位置的点。区间更新是要这样做query(a+2,b,1)因为如果不这样会重复计算。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define lson rt<<1
#define rson rt<<1|1
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void cmax(double& a, double b){ if (a - b < eps) a = b; }
void cmin(double& a, double b){ if (b - a < eps) a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
const int MOD = 1000000007;
const int maxn = 51000;
char str[maxn];
struct SegTree{
int l, r, sum;
int mid(){ return (l + r) >> 1; }
}tree[maxn << 2];
void push_up(int rt){
tree[rt].sum = tree[lson].sum + tree[rson].sum;
}
bool ok(int pos){
if (pos - 2 >= 1 && str[pos - 2] == 'w'&&str[pos - 1] == 'b'&&str[pos] == 'w')
return true;
return false;
}
void build(int l, int r, int rt){
tree[rt].l = l;
tree[rt].r = r;
tree[rt].sum = 0;
if (l == r){
tree[rt].sum = ok(r) ? 1 : 0;
return;
}
int mid = (l + r) >> 1;
build(l, mid, lson);
build(mid + 1, r, rson);
push_up(rt);
}
void update(int pos, int rt){
if (tree[rt].l == tree[rt].r && tree[rt].r == pos){
tree[rt].sum = ok(pos) ? 1 : 0;
return;
}
int mid = tree[rt].mid();
if (pos <= mid)
update(pos, lson);
else if (pos >= mid + 1)
update(pos, rson);
push_up(rt);
}
int query(int l, int r, int rt){
if (l <= tree[rt].l && tree[rt].r <= r){
return tree[rt].sum;
}
int res = 0;
int mid = tree[rt].mid();
if (l <= mid) res += query(l, r, lson);
if (mid + 1 <= r) res += query(l, r, rson);
return res;
}
int main(){
//freopen("E:\\read.txt", "r", stdin);
int n, m, T, cas = 1;
int op, a, b;
char c;
scanf("%d", &T);
while (T--){
scanf("%d %d", &n, &m);
scanf("%s", str + 1);
build(1, n, 1);
printf("Case %d:\n", cas++);
while (m--){
scanf("%d", &op);
if (op == 0){
scanf("%d %d", &a, &b);
a++; b++;
if (a + 2 <= b)
printf("%d\n", query(a + 2, b, 1));
else
printf("0\n");
}
else{
scanf("%d %c", &a, &c);
a++;
if (str[a] != c){
str[a] = c;
update(a, 1);
if (a + 1 <= n)
update(a + 1, 1);
if (a + 2 <= n)
update(a + 2, 1);
}
}
}
}
return 0;
}