这个题目就是在一个矩阵里,进行增删查改。(不是很明确)
有接触到一个新的东西,就是这个树形数组。算法真的很精致。看了不少博客。
需要贴出来几个核心函数:(在这里我不解释原理,用到的时候再仔细看吧)
int lowbit(int x)
{
return x&(-x);
}
这个就相当于求一个树的父节点或者子节点用的。
比如求4的父节点那么就是4+lowbit(4),组成他的节点就是4-lowbit(4)
void updata(int x,int y ,int d)
{
for(int i =x ;i<MAX ; i+=lowbit(i))
{
for(int j=y;j<MAX;j+=lowbit(j))
c[i][j] = c[i][j]+d;
}
}
这个就是根据上边那个函数进行更新的,子节点+n,那么父节点也需要+n,差不多就是这个意思。
int getSum(int x ,int y )
{
int sum = 0 ;
for(int i = x ; i>0;i-=lowbit(i))
{
for(int j = y ; j >0 ; j-=lowbit(j))
{
sum+=c[i][j];
}
}
return sum ;
}
这个就是利用上面的减法,进行求和操作。
我们需要一个c数组来存储每个节点的值
用a数组存储方阵中原本的大小。
于是就有了整个代码:如下:
#include <iostream>
#include<cstdio>
#include<string.h>
#include<cmath>
using namespace std;
#define MAX 1005
int c[MAX][MAX];
int a[MAX][MAX];
int lowbit(int x)
{
return x&(-x);
}
void updata(int x,int y ,int d)
{
for(int i =x ;i<MAX ; i+=lowbit(i))
{
for(int j=y;j<MAX;j+=lowbit(j))
c[i][j] = c[i][j]+d;
}
}
int getSum(int x ,int y )
{
int sum = 0 ;
for(int i = x ; i>0;i-=lowbit(i))
{
for(int j = y ; j >0 ; j-=lowbit(j))
{
sum+=c[i][j];
}
}
return sum ;
}
int main(){
int t , n , i , j ;
char s[10];
int x1,y1,x2,y2,n1;
int xmax,xmin,ymax,ymin;
int ans ,k = 0 ;
scanf("%d",&t);
while(t--)
{
k++;
printf("Case %d:\n",k);
ans = 0 ;
memset(c,0,sizeof(c));
scanf("%d",&n);
for(i = 1 ; i < MAX ; i++)
{
for(j = 1 ; j <MAX ; j++)
{
a[i][j]=1;//每个格子一本书
updata(i,j,1);
}
}
while(n--)
{
scanf("%s",&s);
if(s[0]=='S')
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1++;y1++;x2++;y2++;
xmax=max(x1,x2);xmin = min(x1,x2);
ymax=max(y1,y2);ymin = min(y1,y2);
ans = getSum(xmax,ymax)+getSum(xmin-1,ymin-1)-getSum(xmax,ymin-1)-getSum(xmin-1,ymax);
printf("%d\n",ans);
}
if(s[0]=='A')
{
scanf("%d%d%d",&x1,&y1,&n1);
x1++;y1++;
updata(x1,y1,n1);
a[x1][y1]+=n1;//这个是为了
}
if(s[0]=='D')
{
scanf("%d%d%d",&x1,&y1,&n1);
x1++;y1++;
if(n1>=a[x1][y1])
{
updata(x1,y1,-a[x1][y1]);
a[x1][y1]=0;
}else {
updata(x1,y1,-n1);
a[x1][y1]=a[x1][y1]-n1;
}
}
if(s[0]=='M')
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n1);
x1++;y1++;x2++;y2++;
if(n1>=a[x1][y1])
{
updata(x1,y1,-a[x1][y1]);
updata(x2,y2,a[x1][y1]);
a[x2][y2]=a[x2][y2]+a[x1][y1]; //记录剩下的书
a[x1][y1]=0;
}
else
{
updata(x1,y1,-n1);
updata(x2,y2,n1);
a[x2][y2]=a[x2][y2]+n1; //记录剩下的书
a[x1][y1]=a[x1][y1]-n1;
}
}
}
}
}