思路:本来以为是个纯模板题,结果发现初始化时利用Update(i,j,1)的话会超时,应该是C[i][j]=Lowbit(i)*Lowbit(j);还有就是求区间和时要将对角线的两个点转换为主对角线的两点。
Code :
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int MAX_N=1005;
const int MAX_M=1005;
int Q,T;
int a[MAX_N][MAX_M];
LL C[MAX_N][MAX_M];
int Lowbit(int x);
void Update(int x,int y,int p);
LL Query(int x,int y);
int main()
{
ios::sync_with_stdio(false);
cin>>T;
for(int t=1;t<=T;++t)
{
memset(C,0,sizeof(C));
for(int i=1;i<MAX_N;++i)
for(int j=1;j<MAX_M;++j)
{
a[i][j]=1;
C[i][j]=Lowbit(i)*Lowbit(j);
}
cout<<"Case "<<t<<":"<<endl;
cin>>Q;
char c;
int x1,y1,x2,y2,n;
while(Q--){
cin>>c>>x1>>y1;
++x1; ++y1;
if(c=='S'){
cin>>x2>>y2;
++x2; ++y2;
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
--x1; --y1;
LL ans=Query(x2,y2)-Query(x1,y2)-Query(x2,y1)+Query(x1,y1);
cout<<ans<<endl;
}else if(c=='A'){
cin>>n;
a[x1][y1]+=n;
Update(x1,y1,n);
}else if(c=='D'){
cin>>n;
n=min(n,a[x1][y1]);
a[x1][y1]-=n;
Update(x1,y1,-n);
}else if(c=='M'){
cin>>x2>>y2>>n;
++x2; ++y2;
n=min(n,a[x1][y1]);
a[x1][y1]-=n; a[x2][y2]+=n;
Update(x1,y1,-n); Update(x2,y2,n);
}
}
}
return 0;
}
int Lowbit(int x)
{
return x&(-x);
}
void Update(int x,int y,int p)
{
for(int i=x;i<MAX_N;i+=Lowbit(i))
for(int j=y;j<MAX_M;j+=Lowbit(j))
C[i][j]+=p;
}
LL Query(int x,int y)
{
LL ans=0;
for(int i=x;i>0;i-=Lowbit(i))
for(int j=y;j>0;j-=Lowbit(j))
ans+=C[i][j];
return ans;
}