题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0。

解法:这题如果没有那些特定的条件,那么就是一个纯净的二维树状数组。对于题目中的要求需要解决的两个问题是:如何将题目中的曼哈顿距离转化为规则的矩形,以及如何避免开辟一个巨大的数组。

1.如何转化为矩形问题,这里处理的方法就是把所有的点都旋转45度,需要一个2N*2N的数组数组才能容下坐标转换之后的图,坐标的转化方式为nx = x - y + N,  ny = x + y - 1。可以这样看,转化之后的同行相邻两列的坐标差为(-1, 1), 相邻两列相邻两行的坐标差为(1, 1),所以如果以(0, 0)为参考点(即该点转化前后位置不发生变化)的那么(x, y)就变为(x-y, x+y),又因为所有的点都应该在这个2N*2N的矩形中,因此我们给(1,1)这个点衡坐标加上N,纵坐标-1是为了让最靠左边的点的列从1开始,这样转化后(1,1)->(N,1), (1,N)->(1, N), (N, 1)->(2N-1, N), (N, N)->(N, 2N-1)。

2.如何避免开一个大的数组,由于转化之后的数组达到了20000*20000,这个数组我memset后电脑就死机了,神奇的是编译的时候并没有提示该数组过大。一种有效的方法是将二维的坐标hash处理,即找一个大的质数,每次的更新都选择一个合适的一维数组中的数来表示一个二维中的数,有一个地方要特别注意就是查询的时候并不需要hash处理,如果没有某个数对应的hash值话直接就是0了。

感谢 HDU xiaotao的指点,分析了代码后才恍悟此题的精妙HDU-4312同样存在这样的一个坐标的转化过程,有兴趣的可以去做做。

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;const int MOD = 4073989;
int N, M, LIM;
int to[MOD];
int bit[MOD];int hash(int x) {int key = x % MOD;for (int i = key; ; i++) {if (i == MOD) i = 0;if (to[i] && to[i] != x) {}else {to[i] = x;return i;}}
}int search(int x) {int key = x % MOD;for (int i = key; ; i++) {if (i == MOD) i = 0;if (to[i] && to[i] != x) {}else {// 查询并不需要给出一个离散化之后的值 return i;}}
}inline int lowbit(int x) {return x & (-x);
}void add(int x, int y, int val) {for (int i = x; i <= LIM; i += lowbit(i)){for (int j = y; j <= LIM; j += lowbit(j)) {bit[hash(i*LIM+j)] += val;}}
}inline void get(int x, int y, int &rx, int &ry) {rx = x - y + N;ry = x + y - 1;
}int sum(int x, int y) {int ret = 0;for (int i = x; i; i -= lowbit(i)) {for (int j = y; j; j -= lowbit(j)) {ret += bit[search(i*LIM+j)];}}return ret;
}int main() {while (scanf("%d", &N), N) {scanf("%d", &M);LIM = N << 1;memset(to, 0, sizeof (to));memset(bit, 0, sizeof (bit));int x, y, z, p;int rx, ry, x1, y1, x2, y2;for (int i = 0; i < M; ++i) {scanf("%d%d%d%d", &p, &x, &y, &z);get(x, y, rx, ry);if (p == 1) {add(rx, ry, z);} else {x1 = max(1, rx-z);y1 = max(1, ry-z);x2 = min(LIM, rx+z);y2 = min(LIM, ry+z);printf("%d\n", sum(x2, y2)-sum(x1-1, y2)-sum(x2, y1-1)+sum(x1-1,y1-1));}}}return 0;
}

转载于:https://www.cnblogs.com/Lyush/archive/2013/06/05/3119486.html

HDU-4456 Crowd 二维树状数组+坐标转换相关推荐

  1. HDU 5517---Triple(二维树状数组)

    题目链接 Problem Description Given the finite multi-set A of n pairs of integers, an another finite mult ...

  2. hdu 1892【二维树状数组】

    O(∩_∩)O哈哈~二维树状数组被我搞出来了,太开心了,第一道二维树状数组,(- o -)~zZ 虽然中途还是出问题了,就是S询问的时候我没有考虑坐标的大小问题,还是搜了别人的代码才知道的,看来自己考 ...

  3. hdu 5465(二维树状数组)

    二维bit + 尼姆博奕 #include <iostream> #include <cstdio> #include <cstring> #define Max ...

  4. HDU 5465 Clarke and puzzle (二维树状数组维护区间异或)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5465 解题思路: 因为要对大量的区间进行异或,所以考虑用二维树状数组就行维护. #include< ...

  5. hdu 1892二维树状数组

    这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果--结果--水了好多方法都水不过,出题人真狠呐--我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1 ...

  6. HDU - 5517 Triple(三维偏序-二维树状数组/CDQ分治)

    题目链接:点击查看 题目大意:给出 n 个二元对 ( a , b ) 和 m 个三元对 ( c , d , e ),对于所有 b == e 的二元对和三元对,可以通过某种运算形成一个新的三元对 ( a ...

  7. hdu 5465 Clarke and puzzle (二维树状数组+nim博弈)

    解析: 利用二维树状数组来区间询问异或和,以及单点更新,然后利用nim博弈的结论判断胜负. mymy codecode #include <cstdio> #include <cst ...

  8. 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]

    题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...

  9. szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】

    树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...

最新文章

  1. 无人驾驶的落地,是一场AI与人的博弈
  2. 使用Capture 制作元件库
  3. Ubuntu下使用Evernote
  4. 分享Hadoop处理大数据工具及优势
  5. vs release 调试 路径设置
  6. [拓扑排序/强联通分量] [NOIP201402] 信息传递
  7. Delphi XE2 之 FireMonkey 入门(30) - 数据绑定: TBindingsList: TBindExpression 的 OnAssigningValue 事件...
  8. Hive体系结构(二)Hive的执行原理、与关系型数据库的比较
  9. Java问题定位之如何借助线程堆栈进行问题分析
  10. python3哪个版本稳定-python3哪个版本稳定
  11. python爬取换页_爬虫爬不进下一页了,怎么办
  12. 数据结构 堆 栈 是什么 区别
  13. Matlab设置字体大小
  14. nmds与mds的区别_NMDS分析
  15. html简单图片轮播居中,html简单图片轮播的实现
  16. ES6模板字符串if语句判断
  17. 马斯克收购 Twitter 后的 Web3 改革方向
  18. Linux - 部署node项目
  19. Win10下开机自动启动运行bat脚本并打开cmd运行命令
  20. Android -结束当前activity并返回上一个activity

热门文章

  1. 时问轴php,php-发布到时间轴-过去的日期
  2. python数据组织存在维度吗_用Python将统计数据不存在的记录按维度对应指标补齐...
  3. MSHA x Chaos 容灾高可用实践
  4. mysql的topsql_TOP SQL监控之MySQL篇
  5. 格莱泽检验matlab,计量经济学实验指导书
  6. ubuntu版php开发工具,Ubuntu 中搭建 LAMP 及 php 开发工具
  7. linux系统怎么查看权限设置密码,linux系统怎么查看及修改文件读写权限设置
  8. js opacity0点击_javascript opacity兼容性随笔
  9. php双写绕过,高并发下缓存与数据库双写不一致解决方案
  10. mac u盘格式化 linux系统文件,Mac上怎么制作Ubuntu的U盘开启盘(装Linux系统)