一个由b w组成的字符串 两种操作 一是查询给定区间内wbw串的数量 二是改变给定位置的字符
边改变边查询->想到线段树
树节点内sum变量储存对应区间中wbw的数量,update时一并更新即可
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=50010;
char str[N];
int n,m;
struct tree
{
int l,r;
int sum;
}t[N*3];
int cal(int x)
{
if (x+2>=n) return 0;
if (str[x]=='w'&&str[x+1]=='b'&&str[x+2]=='w') return 1;
return 0;
}
void build(int l,int r,int step)
{
t[step].l=l;
t[step].r=r;
if (l==r)
{
t[step].sum=cal(l);
return;
}
int mid=(l+r)/2;
build(l,mid,step*2);
build(mid+1,r,step*2+1);
t[step].sum=t[step*2].sum+t[step*2+1].sum;
}
void update(int step,int addr)
{
if (t[step].l==addr&&t[step].r==addr)
{
t[step].sum=cal(addr);
return;
}
int mid=(t[step].l+t[step].r)/2;
if (mid>=addr) update(step*2,addr);
else update(step*2+1,addr);
t[step].sum=t[step*2].sum+t[step*2+1].sum;
}
int getsum(int l,int r,int step)
{
if (t[step].l==l&&t[step].r==r)
return t[step].sum;
int mid=(t[step].l+t[step].r)/2;
if (mid>=r) return getsum(l,r,step*2);
else if (mid+1<=l) return getsum(l,r,step*2+1);
else return getsum(l,mid,step*2)+getsum(mid+1,r,step*2+1);
}
int main()
{
freopen("in.txt","r",stdin);
int T,num=1,flag,addr,l,r;
char ch;
scanf("%d",&T);
while (T--)
{
scanf("%d%d\n",&n,&m);
scanf("%s",str);
build(0,n-1,1);
printf("Case %d:\n",num);
num++;
for (int i=1;i<=m;i++)
{
scanf("%d",&flag);
if (flag==1)
{
scanf("%d %c",&addr,&ch);
if (str[addr]==ch) continue;
str[addr]=ch;
for (int j=0;j<3;j++)
if (addr-j>=0) update(1,addr-j);
}
else if (flag==0)
{
scanf("%d%d",&l,&r);
if (r-l<2) printf("0\n");
else printf("%d\n",getsum(l,r-2,1));
}
}
}
return 0;
}