poj1195 Mobile phones

题意:

输入一串指令,每个指令一行

指令有4种

第一种:0 S,将一个S*S的矩阵初始化为0,编号为0,1,,,S-1

第二种:1 X Y A,将坐标(X,Y)的值加A

第三种:2 L B R T,求坐标(X,Y)的值总和,L<=X<=R,B<=Y<=T

第四种:3,结束

解法:

我开始想用一维的树状数组做,结果TLE了 。。

正解是二维树状数组,我的第一个二维树状数组

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
long long n;
#define MAX 1030
long long c[MAX][MAX];//二维的树状数组
long long lowbit(long long x)
{
	return x&(-1*x);
}
void update(long long x,long long y,long long num)//和一维的很像吧。。
{
	for(long long i=x;i<=n;i+=lowbit(i))
	{
		for(long long j=y;j<=n;j+=lowbit(j))
		{
			c[i][j]+=num;
		}
	}
}
long long getsum(long long x,long long y)//二维树状数组的求和函数
{
	long long ans=0;
	for(long long i=x;i>=1;i-=lowbit(i))
	{
		for(long long j=y;j>=1;j-=lowbit(j))
		{
			ans+=c[i][j];
		}
	}
	return ans;
}
int main()
{
	long long type;
	scanf("%lld %lld",&type,&n);
	memset(c,0,sizeof(c));//树状数组的初始化
	while(scanf("%lld",&type),type!=3)
	{
		if(type==1)
		{
			long long x,y,num;
			scanf("%lld %lld %lld",&x,&y,&num);
			x++;y++;//这里要加1,因为输入中有0,我把所有序号都做加1的处理
			update(x,y,num);
		}
		else
		{
			long long x1,y1,x2,y2;
			scanf("%lld %lld %lld %lld",&x1,&y1,&x2,&y2);
			x1++;
			y1++;
			x2++;
			y2++;//加1的原因同上
			printf("%lld\n",getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1));//
		}
	}
	return 0;
}


你可能感兴趣的:(poj1195 Mobile phones)