HDU_2642_Stars

假设flag[i][j]=1表示灯亮,flag[i][j]=0表示灯灭

只有两种情况需要更新树状数组:

1、flag[x1][y1]=1,命令是D,add(x1,y1,1)

2、flag[x1][y1]=0,命令是B,add(x1,y1,-1)

由于树状数组的下标从1开始,而x1,y1有可能等于0,所以自增1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
#define N 1005
int C[N][N]; //定义的全局变量,一开头初始值都是0
bool flag[N][N];
int sum(int x,int y) //x是横坐标,y是纵坐标
{
    int ret=0,i,j;
    for(i=x;i>0;i-=(i&-i))
        for(j=y;j>0;j-=(j&-j))
            ret+=C[i][j];
    return ret;
}
void add(int x,int y,int d) //d是需要增加的值
{
    int i,j;
   for(i=x;i<N;i+=(i&-i))
       for(j=y;j<N;j+=(j&-j))
           C[i][j]+=d;
}
int main()
{
 int t,a,b,c,d;
 char ask[5];
 scanf("%d",&t);
 while(t--)
 {
     scanf("%s",ask);
     if(ask[0]=='B')
     {
         scanf("%d%d",&a,&b);
         if(!flag[a+1][b+1])
         {
             flag[a+1][b+1]=1;
             add(a+1,b+1,1);
         }
     }
     else if(ask[0]=='D')
     {
         scanf("%d%d",&a,&b);
         if(flag[a+1][b+1])
         {
             flag[a+1][b+1]=0;
             add(a+1,b+1,-1);
         }
     }
     else{
         scanf("%d%d%d%d",&a,&b,&c,&d); //略坑,没有看清题目,前面两个是两个点的横坐标
         if(a>b) swap(a,b);
         if(c>d) swap(c,d);
         printf("%d\n",sum(b+1,d+1)-sum(b+1,c)-sum(a,d+1)+sum(a,c));
     }
 }
 return 0;
}

 

 

posted @ 2013-05-22 11:16  小仪在努力~  阅读(228)  评论(0编辑  收藏  举报