数方格 | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
Description | ||||||||||||||||||||||||||||||
有一个S*S的方格,行和列都是从0到S-1。 有四种操作:
范围限制:
| ||||||||||||||||||||||||||||||
Input | ||||||||||||||||||||||||||||||
本题只有一组测试数据。 第一行为操作0。 最后一行为操作3。 中间操作数不多于60000。 | ||||||||||||||||||||||||||||||
Output | ||||||||||||||||||||||||||||||
输入输出格式请参考Description和Sample。 | ||||||||||||||||||||||||||||||
Sample Output | ||||||||||||||||||||||||||||||
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3 | ||||||||||||||||||||||||||||||
Hint | ||||||||||||||||||||||||||||||
3 4 | ||||||||||||||||||||||||||||||
Source | ||||||||||||||||||||||||||||||
2014暑假集训练习赛(7月30日) |
思路:
对应每一个操作都有对应的分步处理。
对应update操作:
if(op==1)
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
update(x+1,y+1,val);//对应点的入图。
}
对应query操作:
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int c=getsum(x1,y1);
int d=getsum(x2+1,y2+1);
int e=getsum(x1,y2+1);
int f=getsum(x2+1,y1);
printf("%d\n",d-e-f+c);
完整的AC代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int m;
int a[1030][1030];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,int d)
{
int temp=y;
while(x<=m)
{
y=temp;
while(y<=m)
{
a[x][y]+=d;
y=y+lowbit(y);
}
x=x+lowbit(x);
}
}
int getsum(int x,int y)
{
int sum=0;
int temp=y;
while(x>0)
{
y=temp;
while(y>0)
{
sum=sum+a[x][y];
y=y-lowbit(y);
}
x=x-lowbit(x);
}
return sum;
}
int main()
{
int op;
while(~scanf("%d",&op))
{
if(op==3)break;
if(op==0)
{
memset(a,0,sizeof(a));
scanf("%d",&m);
}
if(op==1)
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
update(x+1,y+1,val);
}
if(op==2)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int c=getsum(x1,y1);
int d=getsum(x2+1,y2+1);
int e=getsum(x1,y2+1);
int f=getsum(x2+1,y1);
printf("%d\n",d-e-f+c);
}
}
}