Counting Black(树状数组)

 

Problem O

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 14   Accepted Submission(s) : 12
Problem Description
There is a board with 100 * 100 grids as shown below. The left-top gird is denoted as (1, 1) and the right-bottom grid is (100, 100). 

We may apply three commands to the board: 
1.	WHITE  x, y, L     // Paint a white square on the board, 

                           // the square is defined by left-top grid (x, y)

                           // and right-bottom grid (x+L-1, y+L-1)



2.	BLACK  x, y, L     // Paint a black square on the board, 

                           // the square is defined by left-top grid (x, y)

                           // and right-bottom grid (x+L-1, y+L-1)



3.	TEST     x, y, L    // Ask for the number of black grids 

                            // in the square (x, y)- (x+L-1, y+L-1) 

In the beginning, all the grids on the board are white. We apply a series of commands to the board. Your task is to write a program to give the numbers of black grids within a required region when a TEST command is applied. 
 

Input
The first line of the input is an integer t (1 <= t <= 100), representing the number of commands. In each of the following lines, there is a command. Assume all the commands are legal which means that they won't try to paint/test the grids outside the board.
 

Output
For each TEST command, print a line with the number of black grids in the required region.
 

Sample Input
  
  
5 BLACK 1 1 2 BLACK 2 2 2 TEST 1 1 3 WHITE 2 1 1 TEST 1 1 3
 

Sample Output
  
  
7 6
 

Statistic |  Submit |  Back

题意:

BLACK x y l是指将第x行,y列到第x+l-1行,y+l-1列翻成黑色(初始化时为白色)

WHITE x y l是指将第x行,y列到第x+l-1行,y+l-1列翻成白色(初始化时为白色)

TEST x y l是指求从第x行,y列到第x+l-1行,y+l-1列中白色的有几个

思路:

一开始想的用数状数组,其实这个题目不用树状数组也能过。。。数状数组是更新一个二维区间,查找一个二维区间两个函数,其中更新区间

树状数组代码:

#include <iostream>
#include <cstring>
#define MAX_N 105
using namespace std;

int num[MAX_N + 1][MAX_N + 1];
int color[MAX_N + 1][MAX_N + 1];
int lowbit(int id)
{
    return id & (id ^ (id - 1));
}

void modify(int x, int y, int change)
{
    int i, j;
    int val;
    if(color[x][y] == change) return;
    if(change == 1) val = 1;
    else if(color[x][y] == 1) val = -1;
    color[x][y] = change;
    if(val == 0) return;

    for(i = x; i <= MAX_N; i += lowbit(i))
        for(j = y; j <= MAX_N; j += lowbit(j))
            num[i][j] += val;
}

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

int main()
{
    int cn;
    char command[10];
    int x, y, L, i, r, c;
    scanf("%d", &cn);
    for(i = 1; i <= cn; i++)
    {
        scanf("%s%d%d%d", command, &x, &y, &L);
        if(strcmp(command, "WHITE") == 0)
        {
            for(r = x; r < x + L; r++)
                for(c = y; c < y + L; c++)
                    modify(r, c, 0);
        }
        else if(strcmp(command, "BLACK") == 0)
        {
            for(r = x; r < x + L; r++)
                for(c = y; c < y + L; c++)
                    modify(r, c, 1);
        }
        else
        {
            int count1 = sum(x + L - 1, y + L - 1);
            int count2 = sum(x + L - 1, y - 1);
            int count3 = sum(x - 1, y + L - 1);
            int count4 = sum(x - 1, y - 1);
            printf("%d\n", count1 - count2 - count3 + count4);
        }
    }
    return 0;
}
非数状数组代码:

#include<stdio.h>  
#include<iostream>  
#include<string.h>  
#include<cstring>  
using namespace std;  
  
int mp[102][102]; 
void update(int x,int y,int l,char color)  
{   
	int i,j;  
    for(i=x;i<=x+l-1;i++)  
    {  
        for(j=y;j<=y+l-1;j++)  
        {  
            if(color=='B')  
                mp[i][j]=1;  
            else if(color=='W')  
                mp[i][j]=0;  
        }  
    }  
}  
  
int count(int x,int y,int l)  
{  
    int i,j;  
    int sum=0;  
    for(i=x;i<=x+l-1;i++)  
    {  
        for(j=y;j<=y+l-1;j++)  
            if(mp[i][j]==1)  
        sum++;  
    }  
    return sum;  
}  

int main()  
{  
    int T;  
    int x,y,l;  
    
    while(scanf("%d",&T)!=EOF)  
    {  
        memset(mp,0,sizeof(mp));  
        while(T--)  
        {  
            char str[6];  
            cin>>str>>x>>y>>l;  
            if(str[0]=='B')  
            {  
                update(x,y,l,'B');  
            }  
            else if(str[0]=='W')  
            {
                update(x,y,l,'W');  
            }  
            else if(str[0]=='T')  
            {  
                printf("%d\n",count(x,y,l));  
            }  
              
        }  
    }  
    return 0;  
}  



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值