题目大意:http://acm.hdu.edu.cn/showproblem.php?pid=4456
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
const int maxn =4e6+5;
const int mod=1e9+7;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:给定一个二维平面,
支持两种操作,添加平面一点的权值,查询曼哈顿距离范围的权值和。
首先把坐标处理下,把其中的菱形全部映射成矩形方便查询。
(x->x-y+n,y->x+y),然后这道题有两个问题,
范围太大数组存不下,但总共的点数很小,难免想到离散化技术,
这题要是直接用MAP做的话就结束了。。(Map也会爆空间,,可惜)。
我们不妨把连同涉及树状数组操作的点都提取出来,
存到一个栈中,组成了一个答案的映射集合,题目的答案完全可以通过这个集合找出来。
映射到一维栈中简单的用一下hash技术,然后用lower_bound映射成一维点。
(这道题不是自己独立做的,,,也算是学到了这种哈希+离散化的技术。)
*/
int n,m,O[maxn],X[maxn],Y[maxn],W[maxn];///选择,下标与权重
int w,H[maxn+5],E,bit[maxn+5];
int lowbit(int x){return x&(-x);}
int Find(int x){return lower_bound(H+1,H+E,x)-H;}
void HashPoint(int x,int y)
{
for(int i=x;i<=w;i+=lowbit(i))
for(int j=y;j<=w;j+=lowbit(j))
H[E++]=i*w+j;
}
void add(int x,int y,int d)
{
for(int i=x;i<=w;i+=lowbit(i))
for(int j=y;j<=w;j+=lowbit(j))
{
int pos=Find(i*w+j);
bit[pos]+=d;
}
}
int sum(int x,int y)
{
int ret=0;
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
{
int pos=Find(i*w+j);
if(H[pos]==i*w+j) ret+=bit[pos];
}
return ret;
}
void solve()
{
for(int i=1;i<=m;i++)
{
int x=X[i]-Y[i]+n;
int y=X[i]+Y[i];
if(O[i]==1) add(x,y,W[i]);
else
{
int a=max(1,x-W[i]);///细节,别越界
int b=max(1,y-W[i]);
int c=min(w,x+W[i]);
int d=min(w,y+W[i]);
printf("%d\n",sum(c,d)+sum(a-1,b-1)-sum(c,b-1)-sum(a-1,d));
}
}
}
void init()
{
E=1;w=2*n;
memset(bit,0,sizeof(bit));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&O[i],&X[i],&Y[i],&W[i]);
int x=X[i]-Y[i]+n;
int y=X[i]+Y[i];
if(O[i]==1) HashPoint(x,y);
}
sort(H+1,H+E);///哈希+离散化
E=unique(H+1,H+E)-H;
}
int main()
{
while(scanf("%d",&n)&&n)
{
scanf("%d",&m); init();
solve();
}
return 0;
}