树状数组(二维)例题 HDU2642——Stars





//输入B后输入坐标,表示对应的点的灯变亮
//输入D后输入坐标表示对应的点灯灭
//输入Q后输入一个矩形的左下角和右上角 输出矩形内亮着的等的个数
//注:灯亮过不能再亮,灯关了不能再关,所以用数组标记
//注:树状数组模板中:元素下标均从1开始,题目从0开始所以加1
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<iostream>
#include<math.h>
#include<map>
#include<queue>
using namespace std;
#define maxn 1010
#define INF 0x3f3f3f3f
int vis[maxn][maxn];
int c[maxn][maxn];
int lowbit(int x)
{
     return x&(-x);
}
void add(int x,int y,int val)
{
     for(int i=x;i<=maxn;i+=lowbit(i))
     {
          for(int j=y;j<=maxn;j+=lowbit(j))
          {
               c[i][j]+=val;
          }
     }
}
int sum(int x,int y)
{
     int s=0;
     for(int i=x;i>0;i-=lowbit(i))
     {
          for(int j=y;j>0;j-=lowbit(j))
          {
               s+=c[i][j];
          }
     }
     return s;
}
int main()
{
     int m,x1,x2,y1,y2;
     char str[5];
     scanf("%d",&m);

          memset(vis,0,sizeof(vis));
          memset(c,0,sizeof(c));
          while(m--)
          {
               scanf("%s",str);
               if(str[0]=='Q')
               {
                   scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
                   x1++;x2++;y1++;y2++;
                   if(x1>x2){int tmp=x1;x1=x2;x2=tmp;}
                   if(y1>y2){int tmp=y1;y1=y2;y2=tmp;}
                   int ans=sum(x2,y2)-sum(x2,y1-1)-sum(x1-1,y2)+sum(x1-1,y1-1);
                   printf("%d\n",ans);
               }
               else if(str[0]=='B')
               {
                    scanf("%d%d",&x1,&y1);
                    x1++;y1++;
                    if(vis[x1][y1]==1) continue;
                    vis[x1][y1]=1;
                    add(x1,y1,1);
               }
               else if(str[0]=='D')
               {
                    scanf("%d%d",&x1,&y1);
                    x1++;y1++;
                    if(vis[x1][y1]==0) continue;
                    vis[x1][y1]=0;
                    add(x1,y1,-1);
               }
          }

     return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值