[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;
}
posted @ 2018-08-12 23:39  Wolfycz  阅读(448)  评论(0编辑  收藏  举报