Mobile phones poj1195 二维线段树

http://poj.org/problem?id=2155

依旧照着老师的代码敲的。

... 有的时候发现自己确实不合格做一个Acmer ..


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MY_MAX 1100

/*二维线段树,每一行都是一棵完全二叉树,用于存放一棵x方向线段树,数节点只存放对应区间(矩阵)的数字之和*/
int Tree[MY_MAX*2][MY_MAX*2];
int S;//矩阵宽度

void Add_x(int rooty,int rootx,int L,int R,int x,int a){
//rooty是外维节点,rootx是内维节点,rootx对应的区间是[L,R]
	Tree[rooty][rootx]+=a;
	if (L==R)
		return ;
	int mid=(L+R)/2;
	if (x<=mid)
		Add_x(rooty,(rootx<<1)+1,L,mid,x,a);
	else
		Add_x(rooty,(rootx<<1)+2,mid+1,R,x,a);
}

void Add_y(int rooty,int L,int R,int y,int x,int a){
//rooty 是外维(y方向)节点,其对应的区间是[L,R]
	Add_x(rooty,0,1,S,x,a);
	if (L==R)
		return ;
	int mid=(L+R)/2;
	if (y<=mid)
		Add_y((rooty<<1)+1,L,mid,y,x,a);
	else Add_y((rooty<<1)+2,mid+1,R,y,x,a);
}

int QuerySum_x(int rooty,int rootx,int L,int R,int x1,int x2){
	if (L==x1&&R==x2)
		return Tree[rooty][rootx];
	int mid=(L+R)/2;
	if (x2<=mid)
		return QuerySum_x(rooty,(rootx<<1)+1,L,mid,x1,x2);
	else if (x1>=mid+1)
		return QuerySum_x(rooty,(rootx<<1)+2,mid+1,R,x1,x2);
	else return QuerySum_x(rooty,(rootx<<1)+1,L,mid,x1,mid)+QuerySum_x(rooty,(rootx<<1)+2,mid+1,R,mid+1,x2);
}

int QuerySum_y(int rooty,int L,int R,int y1,int y2,int x1,int x2){
	if (L==y1&&R==y2)
		return QuerySum_x(rooty,0,1,S,x1,x2);
	int mid=(L+R)/2;
	if (y2<=mid)
		return QuerySum_y((rooty<<1)+1,L,mid,y1,y2,x1,x2);
	else if (y1>=mid+1)
		return QuerySum_y((rooty<<1)+2,mid+1,R,y1,y2,x1,x2);
	else return QuerySum_y((rooty<<1)+1,L,mid,y1,mid,x1,x2)+QuerySum_y((rooty<<1)+2,mid+1,R,mid+1,y2,x1,x2);
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif
	int cmd;
	int x,y,a,l,b,r,t;
	while (true){
		scanf("%d",&cmd);
		switch(cmd){
		case 0:
			scanf("%d",&S);
			memset(Tree,0,sizeof(Tree));
			break;
		case 1:
			scanf("%d%d%d",&x,&y,&a);
			Add_y(0,1,S,y+1,x+1,a);
			break;
		case 2:
			scanf("%d%d%d%d",&l,&b,&r,&t);
			printf("%d\n",QuerySum_y(0,1,S,b+1,t+1,l+1,r+1));
			break;
		case 3:
			return 0;
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值