题目大意:对于一个给定的字符串(有‘b’和‘w’组成),求其中“wbw”的数目。
这题刚开始做时没什么思路,或许跟我本来就讨厌字符串这类题有关吧。好,废话少说,讲讲思路吧。
这题其实是考线段树的,单点更新,区间合并。合并时要注意一下边界,详细的还是自己看看代码吧。
View Code
1 #include <stdio.h> 2 #define lson l,m,rt<<1 3 #define rson m+1,r,rt<<1|1 4 #define maxn 50000 5 struct node 6 { 7 int cnt; 8 }setree[maxn<<2]; 9 char s[50005]; 10 void pushup(int rt,int len,int m,int l,int r) 11 { 12 setree[rt].cnt=setree[rt<<1].cnt+setree[rt<<1|1].cnt; 13 if(len>2){ 14 if(s[m-1]=='w'&&s[m]=='b'&&s[m+1]=='w'&&m>l) 15 setree[rt].cnt++; 16 else if(s[m]=='w'&&s[m+1]=='b'&&s[m+2]=='w'&&m<r-1) 17 setree[rt].cnt++; 18 } 19 } 20 void build(int l,int r,int rt) 21 { 22 if(l==r){ 23 setree[rt].cnt=0; 24 return; 25 } 26 int m=(l+r)>>1; 27 build(lson); 28 build(rson); 29 pushup(rt,r-l+1,m,l,r); 30 } 31 void update(int l,int r,int rt,int num) 32 { 33 if(l==r) 34 return; 35 int m=(l+r)>>1; 36 if(num<=m) 37 update(lson,num); 38 else 39 update(rson,num); 40 pushup(rt,r-l+1,m,l,r); 41 } 42 int query(int l,int r,int rt,int L,int R) 43 { 44 if(L<=l&&r<=R) 45 return setree[rt].cnt; 46 int m=(l+r)>>1; 47 if(R<=m) 48 return query(lson,L,R); 49 else if(L>m) 50 return query(rson,L,R); 51 else{ 52 int ans=query(lson,L,m)+query(rson,m+1,R); 53 if(s[m-1]=='w'&&s[m]=='b'&&s[m+1]=='w'&&m>L&&m<R) 54 ans++; 55 else if(s[m]=='w'&&s[m+1]=='b'&&s[m+2]=='w'&&m>=L&&m<R-1) 56 ans++; 57 return ans; 58 } 59 } 60 int main() 61 { 62 int t,cas=1; 63 scanf("%d",&t); 64 while(t--){ 65 int n,m; 66 scanf("%d%d",&n,&m); 67 scanf("%s",s); 68 build(0,n-1,1); 69 printf("Case %d:\n",cas++); 70 while(m--){ 71 int op; 72 scanf("%d",&op); 73 if(op==1){ 74 int num; 75 char opp[5]; 76 scanf("%d%s",&num,opp); 77 s[num]=opp[0]; 78 update(0,n-1,1,num); 79 } 80 else{ 81 int l,r; 82 scanf("%d%d",&l,&r); 83 printf("%d\n",query(0,n-1,1,l,r)); 84 } 85 } 86 } 87 }