将坐标轴旋转45°,再乘√2 y’=y-x x’=x+y,这样子原来的菱形就变成了矩形,因为y-x可以是负数,所以加上(N=2*n)
但是数组开不下,用hash函数 a*N+b来离散化,sort排序,再unique去重。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=80008;
const int MAXH=2500008;
int p[MAX],x[MAX],y[MAX],z[MAX],h[MAXH],a[MAXH],cnt,N;
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y,int v)
{
int i,j,num;
for(i=x;i<=N;i+=lowbit(i))
for(j=y;j<=N;j+=lowbit(j))
{
num=lower_bound(h,h+cnt,i*N+j)-h;
a[num]+=v;
}
}
int getsum(int x,int y)
{
int i,j,num,sum=0;
for(i=x;i>0;i-=lowbit(i))
for(j=y;j>0;j-=lowbit(j))
{
num=lower_bound(h,h+cnt,i*N+j)-h;
if(h[num]==i*N+j) sum+=a[num];
}
return sum;
}
void make_hash(int x,int y)
{
int i,j;
for(i=x;i<=N;i+=lowbit(i))
for(j=y;j<=N;j+=lowbit(j))
h[cnt++]=i*N+j;
}
int main()
{
int i,b,c,m,n,x1,x2,y1,y2,ans1,ans2,ans3,ans4;
while(scanf("%d",&n)!=EOF&&n)
{
cnt=0;
memset(a,0,sizeof(a));
scanf("%d",&m);
N=n<<1;
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&p[i],&c,&b,&z[i]);
x[i]=c-b+n;
y[i]=c+b;
if(p[i]==1) make_hash(x[i],y[i]);
}
sort(h,h+cnt);
cnt=unique(h,h+cnt)-h;
for(i=1;i<=m;i++)
{
if(p[i]==1) add(x[i],y[i],z[i]);
else
{
x1=max(1,x[i]-z[i]);
x2=min(N,x[i]+z[i]);
y1=max(1,y[i]-z[i]);
y2=min(N,y[i]+z[i]);
ans1=getsum(x1-1,y1-1);
ans2=getsum(x2,y1-1);
ans3=getsum(x1-1,y2);
ans4=getsum(x2,y2);
printf("%d\n",ans4+ans1-ans2-ans3);
}
}
}
}