See you~
题目连接: 点击打开链接
题目描述:在一个最大为1000*1000的图上,每个格子里事先放一本书,现在有四种操作如下;
//S 读取x1 y1 到 x2 y2之间的总数
//A 在x y 位置放n1 本书
//D 在x y 拿走n1本,不n1就全取走
//M 将x1 y1 移动到 x2 y2 n1个不够则全部移走
注意:(1) x1 y1 到 x2 y2 可能不是正对角线;
(2)坐标从0开始,对其操作要加1,否则会死循环。
代码如下:
#include<stdio.h>
#include<string.h>
#define MAXN 1005
#define MIN(a,b) (a<b?a:b)
int tree[MAXN][MAXN];
void add(int x,int y,int num)
{
for(int i=x;i<=MAXN;i+=i&(-i))
for(int j=y;j<=MAXN;j+=j&(-j))
tree[i][j]+=num;
}
int read(int x,int y)
{
int sum=0;
for(int i=x;i>0;i-=i&(-i))
for(int j=y;j>0;j-=j&(-j))
sum+=tree[i][j];
return sum;
}
int getdan(int x,int y)
{
return read(x,y)-read(x-1,y)-read(x,y-1)+read(x-1,y-1);
}
void S()
{
int sum,tem;
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1++;x2++;y1++;y2++;
if(x1>x2) { tem=x1;x1=x2;x2=tem; }
if(y1>y2) { tem=y1;y1=y2;y2=tem; }
sum=read(x2,y2)-read(x2,y1-1)-read(x1-1,y2)+read(x1-1,y1-1);
printf("%d\n",sum);
}
void A()
{
int x,y,num;
scanf("%d%d%d",&x,&y,&num);
x++;y++;
add(x,y,num);
}
void D()
{
int x,y,num;
scanf("%d%d%d",&x,&y,&num);
x++;y++;
int var=getdan(x,y);
num=MIN(num,var);
add(x,y,-num);
}
void M()
{
int x1,x2,y1,y2,num;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&num);
x1++;x2++;y1++;y2++;
int var=getdan(x1,y1);
num=MIN(num,var);
add(x1,y1,-num);
add(x2,y2,num);
}
int main()
{
int t;
int index=1;
int n;
char x;
scanf("%d",&t);
while(t--)
{
memset(tree,0,sizeof(tree));
for(int i=1;i<MAXN;i++)
for(int j=1;j<MAXN;j++)
add(i,j,1);
printf("Case %d:\n",index++);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
getchar();
scanf("%c",&x);
if(x=='S')
S();
else if(x=='A')
A();
else if(x=='D')
D();
else if(x=='M')
M();
}
}
return 0;
}