HLJU 1188 Matrix (二维树状数组)
来源:互联网 发布:tita软件 编辑:程序博客网 时间:2024/06/05 17:06
Matrix
Time Limit: 4 Sec Memory Limit: 128 MBDescription
给定一个1000*1000的二维矩阵,初始矩阵中每个数都为1,然后为矩阵有4种操作.
S x1 y1 x2 y2:计算(x1,y1)、(x2,y2)围成的矩阵内所有元素的和。
A x y v:将(x,y)增加v
D x y v:将(x,y)减少v
M x1 y1 x2 y2 v:将(x1,y1)元素中的v转移到(x2,y2)中去。
所有操作数都为正数。
若某一操作将矩阵中元素降到1以下,一律按1处理。
x,y从0开始编号。
Input
第一行一个数t,代表样例个数:
每组样例第一行一个数m,代表m次操作,m<100000
接下来m行代表m次操作
Output
每组样例输出一个
Case i:
i代表第i个样例
对于每一个操作S,输出一行,代表计算结果。
所有结果均不会超过int范围
Sample Input
14A 1 1 1M 1 1 2 2 1D 2 2 1S 1 1 2 2
Sample Output
Case 1:4
解题思路:很明显的就是一个很典型的二维树状数组问题,树状数组部分完全就是模板,只是要在具体解决实际问题的时候,有点技巧。最开始见到这题的时候,我立即想到了以前切的楼教主出的Matrix,感觉很相似,然后就直接搞了,后来发现开始,要初始化树状数组的c数组,由于矩阵的初值均为1,就用了两层循环,一个一个调用update(),结果竟然超时了。。。然后又在其他地方优化了,还是超时。。。就想了个办法,直接把c数组全部初始化为0,这样就不用一次次的去调用update()了(因为c要存的是他前面的和,现在全为0,和当然也为0了),然后在求区域和的时候,直接加上那个区间里的节点数(因为本来的矩阵中应该全部初始化为1的,但是我开始全初始化为0了,就把每个节点都少了1,节点数也就是区间的面积)即可。还有就是要求保证原矩阵元素在操作之后不能小于1,具体可以先算出当前位置的元素值, 在操作之前把操作的数e修改,然后直接执行操作即可。这里还学到了一个求当前位置元素的方法,直接用区域求和函数,对当前点求和,即map[a][b] = getsum( a, b, a, b ). 详见代码
楼教主的Matrix 见:http://blog.csdn.net/u013446688/article/details/38194977
AC代码:
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int maxn = 1002;#define lowbit(x)x & (-x) //lowbit函数 int c[maxn][maxn]; //树状数组的c数组inline int update(int x, int y, int d){ //update函数 int i, j;for(i=x; i<=1000; i+=lowbit(i))for(j=y; j<=1000; j+=lowbit(j))c[i][j] += d;}inline int sum(int x, int y){ //sum函数 int ans = 0;int i, j;for(i=x; i>0; i-=lowbit(i))for(j=y; j>0; j-=lowbit(j))ans += c[i][j];return ans;}int getsum(int x1, int y1, int x2, int y2){ //区域求和return sum(x2, y2) - sum(x1-1, y2) - sum(x2, y1-1) + sum(x1-1, y1-1);}int main(){//freopen("in.txt","r",stdin);int T, m ,a, b, cc, d, e;string p;scanf("%d", &T);for(int t=1; t<=T; t++){scanf("%d", &m);printf("Case %d:\n", t);memset(c, 0, sizeof(c));while(m--){cin>>p;if(p[0] == 'A'){scanf("%d%d%d", &a, &b, &e);a++; b++;update(a, b, e);}else if(p[0] == 'D'){scanf("%d%d%d", &a, &b, &e);a++; b++;int k = getsum(a, b, a, b); //求当前位置的元素的值if(k - e < 0) e = k; //修改e, 保证操作之后元素不小于1update(a, b, -e);}else if(p[0] == 'M'){scanf("%d%d%d%d%d", &a, &b, &cc, &d, &e);a++; b++; cc++; d++;int k = getsum(a, b, a, b); //同上if(k - e < 0) e = k;update(a, b, -e);update(cc, d, e);}else{scanf("%d%d%d%d", &a, &b, &cc, &d);a++; b++; cc++; d++;if(cc < a) swap(a, cc);if(d < b) swap(b, d);int ans = getsum(a, b, cc, d) + (cc-a+1)*(d-b+1); //求矩阵区域和printf("%d\n",ans);}}}return 0;}
- HLJU 1188 Matrix (二维树状数组)
- Matrix(二维树状数组)
- poj 2155 Matrix(二维树状数组)
- POJ 2155 Matrix (二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ2155--Matrix(二维树状数组)
- 【树状数组(二维)】poj 2155 Matrix
- POJ 2155 Matrix (二维树状数组)
- [poj 2155] Matrix(二维树状数组)
- POJ2155 Matrix (二维树状数组)
- poj2155--Matrix(二维树状数组)
- POJ 2155 Matrix (二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ Matrix ( 二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- 解决display:inline-block 出现的间隙
- ASP.NET动态创建Media标签
- Java阻塞队列的实现
- 区位码、国标码、机内码、GBK
- Add two numbers & Add binary
- HLJU 1188 Matrix (二维树状数组)
- 产品设计必读书籍推荐
- ios 编译openssl支持arm64
- 使用git提取Minix_R3.2.1源码
- Cocos2d-x_一个简单的Cocos2d-x程序
- Apache二级域名实现
- 第二届战神杯线上编程挑战赛月赛第二题:数字游戏(Java)
- Android 从相册获取最近拍摄的多张照片(获取相机拍照所存储的照片)
- Ubuntu下SSH的安装