1157: 新年彩灯Ⅱ
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 56 Solved: 17
[Submit][Status][Web Board]
Description
新年将至,YY准备挂一片彩灯,形状呈矩形,已知彩灯刚挂完的彩灯共有N*N盏(第一排编号为(1,1),(1,2),(1,3),……,第二排编号为(2,1),(2,2),(2,3)……第N排编号为(N,1),(N,2)……(N,N)),并且都是灭的。彩灯的闪烁由一段程序控制。
每一秒钟程序会生成四个正整数a1,b1,a2,b2(1<=a1,b1,a2,b2<=N),然后将编号(x,y)满足x在a1与a2之间,y在b1与b2之间的灯状态改变一次,即如果灯(x,y)是灭的,那么经过一次改变,灯(x,y)会亮,如果灯(x,y)是亮的,经过一次改变,灯(x,y)会灭。
当YY看着自己挂的彩灯不断闪烁的时候,问题来了,YY想知道任意时刻某盏灯的状态。
Input
多组测试数据,每一组第一行是一个整数N(1<=N<=1000)和一个整数M(1<=M<=3000)。
然后是M行数据,包括以下两种形式:
1 a1 b1 a2 b2 表示将编号(x,y)满足x在a1与a2之间,y在b1与b2之间的灯状态改变一次。
0 x y 表示YY想知道此刻编号(x,y)的灯状态。
Output
对于每组测试数据首先输出“Case #:”('#'表示case序数)
对于每次YY想知道结果的时候,输出灯的状态,如果是亮的输出”1”,否则输出”0”;
Sample Input
3 5
1 1 1 2 2
1 2 2 3 3
0 1 1
0 2 2
0 3 3
2 3
0 1 1
1 1 1 2 2
0 1 1
Sample Output
Case 1:
1
0
1
Case 2:
0
1
二维树状数组单点查询
#include<bits/stdc++.h>
using namespace std;
#define e exp(1)
#define pi acos(-1)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define mem(a,b) memset(a,b,sizeof(a))
int gcd(int a,int b){return b?gcd(b,a%b):a;}
const int maxn=1010;
int n,m,q;
int c[maxn][maxn];
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y,int v)
{
int yy=y;
while(x<=n)
{
y=yy;
while(y<=n)
{
c[x][y]+=v;
y+=lowbit(y);
}
x+=lowbit(x);
}
}
int getsum(int x,int y)
{
int sum=0;
int yy=y;
while(x>0)
{
y=yy;
while(y>0)
{
sum+=c[x][y];
y-=lowbit(y);
}
x-=lowbit(x);
}
return sum;
}
int main()
{
int cas=1;
while(~scanf("%d%d",&n,&m))
{
mem(c,0);
printf("Case %d:\n",cas++);
while(m--)
{
int q;scanf("%d",&q);
if(q==1)
{
int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1>x2)
{
int t=x1;
x1=x2;
x2=t;
}
if(y1>y2)
{
int t=y1;
y1=y2;
y2=t;
}
add(x1,y1,1);
add(x1,y2+1,-1);
add(x2+1,y1,-1);
add(x2+1,y2+1,1);
}
else
{
int x,y;scanf("%d%d",&x,&y);
printf("%d\n",getsum(x,y)&1);
}
}
}
return 0;
}