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; }