[Tyvj1474]打鼹鼠
Description
在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数。这就是你的任务。
Input
每个输入文件有多行。
第一行,一个数n,表示鼹鼠的范围。
以后每一行开头都有一个数m,表示不同的操作:
m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
询问数不会超过10000,鼹鼠数不会超过maxlongint。
Output
对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。
Sample Input
4
1 2 2 5
2 0 0 2 3
3
Sample Output
5
二维线段树板子题,其实二维线段树没那么高大上,维护一个以x排序的线段树,这棵线段树的每个节点都是维护以y排序的线段树,空间\(O(n^2)\),如果n大点就要用到类似主席树的动态开点技巧了
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=1024;
#define ls (p<<1)
#define rs (p<<1|1)
int n;
struct Segment{
int tree[(N<<2)+10];
void change(int p,int l,int r,int x,int v){
if (l==r){
tree[p]+=v;
return;
}
int mid=(l+r)>>1;
if (x<=mid) change(ls,l,mid,x,v);
else change(rs,mid+1,r,x,v);
tree[p]=tree[ls]+tree[rs];
}
int Query(int p,int l,int r,int x,int y){
if (x<=l&&r<=y) return tree[p];
int mid=(l+r)>>1,res=0;
if (x<=mid) res+=Query(ls,l,mid,x,y);
if (y>mid) res+=Query(rs,mid+1,r,x,y);
return res;
}
}T[(N<<2)+10];
void change(int p,int l,int r,int x,int y,int v){
T[p].change(1,0,n,y,v);
if (l==r) return;
int mid=(l+r)>>1;
if (x<=mid) change(ls,l,mid,x,y,v);
else change(rs,mid+1,r,x,y,v);
}
int Query(int p,int l,int r,int x,int y,int X,int Y){
if (x<=l&&r<=y) return T[p].Query(1,0,n,X,Y);
int mid=(l+r)>>1,res=0;
if (x<=mid) res+=Query(ls,l,mid,x,y,X,Y);
if (y>mid) res+=Query(rs,mid+1,r,x,y,X,Y);
return res;
}
int main(){
n=read();
while (true){
int t=read();
if (t==1){
int x=read(),y=read(),k=read();
change(1,0,n,x,y,k);
}
if (t==2){
int ox=read(),oy=read(),ex=read(),ey=read();
printf("%d\n",Query(1,0,n,ox,ex,oy,ey));
}
if (t==3) break;
}
return 0;
}