线段树的查询与更新

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:\n",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\n");
                    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\n",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;
}
View Code

 

 

posted @ 2013-10-22 19:52  清风旋叶  阅读(174)  评论(0编辑  收藏  举报