http://acm.hdu.edu.cn/showproblem.php?pid=4046
非线段树的方法,纯模拟。(AC)
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; const int maxn = 50000+5; char str[maxn]; int vis[5]; int dp[maxn]; int main() { int t,ncas= 1; scanf("%d",&t); while( t-- ) { printf("Case %d: ",ncas++); int n,m; scanf("%d %d",&n,&m); scanf("%s",str); memset( dp,0,sizeof(dp) ); memset( vis,0,sizeof(vis) ); for( int i=2;i<n;i++ ) { if( str[i]=='w'&&str[i-1]=='b'&&str[i-2]=='w' ) { dp[i] = dp[i-1] + 1; } else dp[i] = dp[i-1]; } for( int i=0;i<m;i++ ) { int x; scanf("%d",&x); if( x==0 ) { //cout << "no" << endl; int a,b; scanf("%d %d",&a,&b); if( b-a<2) { printf("0 "); continue; } int ans = dp[b]-dp[a]; if( a-1>=0 && ans ) if( str[a]=='b'&&str[a-1]=='w'&&str[a+1]=='w' ) ans--; printf("%d ",ans); } else { int a; char ch; scanf("%d %c",&a,&ch); if( ch==str[a] ) continue; memset( vis,0,sizeof(vis) ); int cnt = 0,ncnt = 0; for( int i=a,j=0;i<=a+2;i++,j++ ) { if( str[i]=='w'&&str[i-1]=='b'&&str[i-2]=='w' ) { cnt++; vis[j] = 1; } } str[a] = ch; for( int i=a,j=0;i<=a+2;i++,j++ ) { if( str[i]=='w'&&str[i-1]=='b'&&str[i-2]=='w' ) { ncnt++; dp[i]++; if( i+1<=a+2 ) { dp[i+1]++; } if( i+2<=a+2 ) { dp[i+2]++; } } else if( vis[j] ) { dp[i]--; if( i+1<=a+2 ) { dp[i+1]--; } if( i+2<=a+2 ) { dp[i+2]--; } } } for( int i=a+3;i<n;i++ ) { dp[i] += ncnt-cnt; } } } } return 0; }