1014(暴力树状数组)

本文介绍了一种解决二维区间更新与查询问题的方法,通过将区间更新转化为单点更新,并使用二维树状数组来记录每个点的颜色状态。文章提供了一个具体的实现示例,包括白色和黑色方块的绘制以及查询指定区域内黑色方块数量的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题目大概:

对一个区间涂黑或涂白,问一个区间黑色块的数量。

思路:

由于数据量小,直接把区间更新暴力为单点更新并且记录颜色数据。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int n;
int c[102][102];
int vis[102][102];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y,int v)
{   int vv;
    if(vis[x][y]==v)return;
    vis[x][y]=v;
    if(v==1)vv=1;
    else vv=-1;

    for(int i=x;i<=101;i+=lowbit(i))
    {
        for(int j=y;j<=101;j+=lowbit(j))
        c[i][j]+=vv;

    }
}

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

    }
    return su;
}
int main()
{
    int t;
    scanf("%d",&t);
    memset(vis,0,sizeof(vis));
    memset(c,0,sizeof(c));

    while(t--)
    {


       char p[7];
             scanf("%s",p);



             if(p[0]=='B')
             {
                int w1,w2,e1;
                scanf("%d%d%d",&w1,&w2,&e1);
                for(int i=w1;i<w1+e1;i++)
                {
                    for(int j=w2;j<w2+e1;j++)
                    {
                        add(i,j,1);
                    }
                }

             }
             else if(p[0]=='W')
             {
                int w1,w2,e1;
                scanf("%d%d%d",&w1,&w2,&e1);
                for(int i=w1;i<w1+e1;i++)
                {
                    for(int j=w2;j<w2+e1;j++)
                    {
                        add(i,j,0);
                    }
                }
             }
             else if(p[0]=='T')
             {
                 int r1,r2,r3;
                 scanf("%d%d%d",&r1,&r2,&r3);
                 int sun=0;
                 r3--;
                 sun=sum(r1+r3,r2+r3)-sum(r1+r3,r2-1)-sum(r1-1,r2+r3)+sum(r1-1,r2-1);

                 printf("%d\n",sun);
             }




    }





    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值