POJ 1195 Mobile phones 二维树状数组

来源:http://poj.org/problem?id=1195

题意:有一个N * N广场,广场里面有一些手机,某个格子是可以改变的,增加或者减少,问一个小矩阵内有多少个手机。

思路 :裸的二维树状数组。

代码:

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;

typedef long long LL;
const int N = 1030;
int num[N][N];
int lowbit(int x){
	return x & (-x);
}
void update(int x,int y,int add){
	int t = y;
	while(x < N){
	   y = t;
	   while(y < N){
		 num[x][y] += add;
		 if(num[x][y] < 0)
			 num[x][y] = 0;
		 y += lowbit(y);
	   }
	   x += lowbit(x);
	}
}
LL sum(int x,int y){
	int t = y;
	LL s = 0;
	while(x > 0){
	   y = t;
	   while(y > 0){
	     s += num[x][y];
		 y -= lowbit(y);
	   }
	   x -= lowbit(x);
	}
	return s;
}
int main(){
	//freopen("1.txt","r",stdin);
	int id,n;
	while(scanf("%d%d",&id,&n) != EOF){
		memset(num,0,sizeof(num));
		int x1,y1,x2,y2,value;
		while(1){
		  scanf("%d",&id);
		  if(id == 3)
			  break;
		  else if(id == 1){
		     scanf("%d%d%d",&x1,&y1,&value);
			 update(x1+1,y1+1,value);
		  }
		  else if(id == 2){
		    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			printf("%lld\n",sum(x2+1,y2+1) - sum(x1,y2+1) - sum(x2+1,y1) + sum(x1,y1));
		  }
		}
	}
	return 0;
}

HDU  2642   二维树状数组

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;

const int N = 1010;
int num[N][N],dit[N][N];
int lowbit(int x){
	return x & (-x);
}
void update(int x,int y,int add){
	int temp = y;
	while(x < N){
	   y = temp;
	   while(y < N){
	     num[x][y] += add;
		 y += lowbit(y);
	   }
	   x += lowbit(x);
	}
}
int sum(int x,int y){
	int s = 0,temp = y;
	while(x > 0){
	   y = temp;
	   while(y > 0){
	     s += num[x][y];
		 y -= lowbit(y);
	   }
	   x -= lowbit(x);
	}
	return s;
}
int main(){
	int n;
	while(scanf("%d",&n) != EOF){
	   memset(num,0,sizeof(num));
	   memset(dit,0,sizeof(dit));
	   char ss[3];
	   int x1,y1,x2,y2;
	   //getchar();
	   while(n--){
	      scanf("%s",ss);
		  if(ss[0] == 'B'){
		     scanf("%d%d",&x1,&y1);
			 if(!dit[x1+1][y1+1]){
			    update(x1+1,y1+1,1);
				dit[x1+1][y1+1] = 1;
			 }
		  }
		  else if(ss[0] == 'D'){
		     scanf("%d%d",&x1,&y1);
			 if(dit[x1+1][y1+1]){
			   update(x1+1,y1+1,-1);
			   dit[x1+1][y1+1] = 0;
			 }
		  }
		  else{
		     scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
			 int maxx = max(x1,x2), minx = min(x1,x2);
			 int maxy = max(y1,y2), miny = min(y1,y2);
			 printf("%d\n",sum(maxx+1,maxy+1) - sum(minx,maxy+1) - sum(maxx+1,miny) + sum(minx,miny));
		  }
	   }
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值