The QianJin Teaching Building - nazgul's Blog

The QianJin Teaching Building

nazgul posted @ 2010年10月18日 23:46 in HNU , 872 阅读

 

http://acm.hnu.cn/online/?action=problem&type=show&id=11444
二维树状数组支持两种操作,一种修改二维数组中任意元素的值,另一种是查询任意范围的元素和.
 
题目中的4种操作都可以用以上两种操作完成.

#include <stdio.h>
#include <string.h>
#define maxn 1002

int c[maxn][maxn];

int lowbit( int x )
{
    return x & ( -x );
}

int sum( int x, int y )
{
    int i, j, t=0;
    for ( i=x; i>0; i-=lowbit(i) )
        for ( j=y; j>0; j-=lowbit(j) )
            t += c[i][j];
    return t;
}

void Insert( int x, int y, int a )
{
    int i, j;
    for ( i=x; i<maxn; i+=lowbit(i) )
        for ( j=y; j<maxn; j+=lowbit(j) )
            c[i][j] += a;
}

int Query( int x1, int y1, int x2, int y2 )
{
    return sum( x2, y2 )-sum( x1-1, y2 )-sum( x2, y1-1 )+sum( x1-1, y1-1 );
}

int main()
{
    int cases, T, m, x1, y1, x2, y2, v, t;
    char s[2];
    //freopen( "//home//administrator//32.in", "r", stdin );
    //freopen( "//home//administrator//test.out", "w", stdout );
    scanf( "%d", &cases );
    for ( T=1; T<=cases; ++T )
    {
        printf( "Case %d:\n", T );
        memset( c, 0, sizeof( c ) );
        scanf( "%d", &m );
        while ( m-- )
        {
            scanf( "%s", s );
            if ( s[0] == 'A' )
            {
                scanf( "%d%d%d", &x1, &y1, &v );
                x1++; y1++;
                Insert( x1, y1, v );
            }
            else
            if ( s[0] == 'D' )
            {
                scanf( "%d%d%d", &x1, &y1, &v );
                x1++; y1++;
                t = Query( x1, y1, x1, y1 )+1;
                if ( v > t ) v = t;
                Insert( x1, y1, -v );
            }
            else
            if ( s[0] == 'M' )
            {
                scanf( "%d%d%d%d%d", &x1, &y1, &x2, &y2, &v );
                x1++; y1++; x2++; y2++;
                t = Query( x1, y1, x1, y1 )+1;
                if ( v > t ) v = t;
                Insert( x1, y1, -v );
                Insert( x2, y2, v );
            }
            else
            if ( s[0] == 'S' )
            {
                scanf( "%d%d%d%d", &x1, &y1, &x2, &y2 );
                x1++; y1++; x2++; y2++;
                if ( x1 > x2 )
                {
                    v = x1; x1 = x2; x2 = v;
                }
                if ( y1 > y2 )
                {
                    v = y1; y1 = y2; y2 = v;
                }
                v = Query( x1, y1, x2, y2 )+( x2-x1+1 )*( y2-y1+1 );
                printf( "%d\n", v );
            }
        }
    }
    return 0;
}

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee