首页 > 代码库 > POJ1195 Mobile phones 二维树状数组的应用

POJ1195 Mobile phones 二维树状数组的应用

这题可以用线段树离散化做,用二维树状数组做了一下,不懂得可以看一下这篇文章:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804


题意:

给你一个s*s的正方形区域,先输入一个x,若x==0,则再输入一个s,若x==1,则输入x,y,a,表示矩阵中(x,y)这点的值加上a,若x==2,输入l,b,r,t,代表以左上角的点(l,b)右下角的点(r,t),求这一片矩形内的矩阵元素之和,若x==3则结束此次程序


就是最基础的二维树状数组的应用,修改单点的值,并且快速求区间和


#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>

#define ll long long
#define LL __int64
#define eps 1e-8

//const ll INF=9999999999999;

#define inf 0xfffffff

using namespace std;


//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;

int n;

int c[1000 + 35][1000 + 35];

void clear() {
	memset(c,0,sizeof(c));
}

int lowbit(int x) {
	return x&(-x);
}

void add(int x,int y,int value) {
	int i = y;
	while(x <= n) {
		y = i;
		while(y <= n) {
			c[x][y] += value;
			y += lowbit(y);
		}
		x += lowbit(x);
	}
}

int get_sum(int x,int y) {
	int sum=0,i = y;
	while(x > 0) {
		y = i;
		while(y > 0) {
			sum += c[x][y];
			y -= lowbit(y);
		}
		x -= lowbit(x);
	}
	return sum;
}

int main() {
	int x;
	while(true) {
		scanf("%d",&x);
		if(x == 0) {
			scanf("%d",&n);
			n++;
			clear();
		}
		else if(x == 1) {
			int x,y,a;
			scanf("%d %d %d",&x,&y,&a);
			add(++x,++y,a);//矩阵行列标由0开始要处理掉
		}
		else if(x == 2) {
			int l,b,r,t;
			scanf("%d %d %d %d",&l,&b,&r,&t);
			l++,b++,r++,t++;//处理行列标
			int ans = 0;
			//int a1 = get_sum(r,b-1);
			//int a2 = get_sum(l-1,b-1);
			//int a3 = get_sum(r,t);
			//int a4 = get_sum(l-1,t);
			ans = get_sum(r,t) - get_sum(l-1,t) - get_sum(r,b-1) + get_sum(l-1,b-1);
			printf("%d\n",ans);
		}
		else break;
	}
	return 0;
}