链接:http://poj.org/problem?id=1195
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 16646 | Accepted: 7653 |

0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
3 4
Source
大意——给你一个n*n矩阵的区域,它的行列下标都是从0开始的。每个矩阵元素代表一个基站,基站内的处于运行中的手机数量因为各种原因会不断变化。各个基站会不定期地向主基站报告,以便统计运行中的手机数量。你的任务是根据相应的命令完成相应的操作。其中主要的就是更新某一个矩阵元素的值和一个区域的矩阵元素值之和。
思路——很显然这是一个裸的二维树状数组的题。其操作就是更新某一个值和区间求和。因此,我们直接用一维树状数组推广过来即可解决问题。注意:矩阵元素下标从0开始。
复杂度分析——时间复杂度:O((log(n))^2),空间复杂度:O(n^2)
附上AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
//#pragma comment(linker, "/STACK:102400000, 102400000")
using namespace std;
typedef unsigned int li;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double pi = acos(-1.0);
const double e = exp(1.0);
const double eps = 1e-8;
const int maxn = 1030;
int mat[maxn][maxn];
int order; // 键入命令
int n; // 数组大小
int lowbit(int x); // 求2^k,k表示x为二进制时末尾的零的个数
void update(int x, int y, int add); // 更新状态
int sum(int x, int y); // 求和
int main()
{
ios::sync_with_stdio(false);
int x1, y1, x2, y2, add, ans;
while (scanf("%d", &order)==1 && 3!=order)
{
switch(order)
{
case 0:
scanf("%d", &n);
memset(mat, 0, sizeof(mat)); // 初始化为0
break;
case 1:
scanf("%d%d%d", &x1, &y1, &add);
update(x1+1, y1+1, add); // x,y可能为0,所以加1,后面类似
break;
case 2:
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
ans = 0;
ans += sum(x2+1, y2+1); // 总求和
ans -= sum(x2+1, y1);
ans -= sum(x1, y2+1); // 去掉多余部分
ans += sum(x1, y1); // 多减掉一部分,加回来,画图可知
printf("%d\n", ans);
break;
default:
printf("INPUT ERROR!\n");
break;
}
}
return 0;
}
int lowbit(int x)
{
return (x&(-x));
}
void update(int x, int y, int add)
{ // x,y表示矩阵下标,此功能是把下标为x,y的数加上add
for (int i=x; i!=0&&i<=n; i+=lowbit(i))
for (int j=y; j!=0&&j<=n; j+=lowbit(j))
mat[i][j] += add;
}
int sum(int x, int y)
{ // x,y表示矩阵下标,此功能是把下标小于x,y的矩阵元素值加起来
int res = 0;
for (int i=x; i>0; i-=lowbit(i))
for (int j=y; j>0; j-=lowbit(j))
res += mat[i][j];
return res;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/silenceneo/article/details/47746891