转自:http://blog.csdn.net/sdj222555/article/details/10828607

大意就是给出一个矩阵

初始每个位置上的值都为0

然后有两种操作

一种是更改某个位置上的值

另一个是求某个位置附近曼哈顿距离不大于K的所有位置的值的总和

然后这里用了一个非常牛叉的技巧

将所有点绕原点左旋45°

然后新的坐标也很好计算

x' = (x - y) * sqrt(2) / 2

y' = (x + y) * sqrt(2) / 2

由于都是小数

所以乘个sqrt(2) 就成整数了

x' = (x - y)

y' = x + y

由于x- y可能是负数。所以把点都右移一下  x' = x + y + n (n是矩阵宽度)然后矩阵的宽度和长度也就各自扩大了一倍

然后我们就可以惊奇的发现

原先是求 abs(x - x0) + abs(y - y0) <= k 的所有位置的值的和

现在变成了 abs(x' - x0') <= k 或者abs(y' - y0') <= k 就可以了

也就变成了求一个子矩阵的和

然后就可以欢快的用二维树状数组来解了

但是发现题目给的范围比较大

1W*1W的矩阵

但是询问的话 有8W

那么我们可以就把所有询问中树状数组操作过程中用到的点给离散出来。

然后就可以节省内存了

离散的话可以有两种方法

一种是线性探测再散列

这个可以在线处理询问

另一个就是先把所有可能用到的都取出来,然后先都离散了,离线处理询问

离散之后,每个x,y都应该对应一个唯一的数。我们就可以用一个一维的数组,来完成这个二维树状数组的功能

首先是先把询问存起来的离散方式

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio> using namespace std; const int N = ;
const int M = ; int W; // 坐标转换后的边长
int h[M*], cnt;
int bit[M*];
int op[M], x[M], y[M], v[M]; int lowbit(int x) {
return x&-x;
}
void ready(int x, int y) {
for (int i = x; i <= W; i += lowbit(i)) {
for (int j = y; j <= W; j += lowbit(j)) {
h[cnt++] = i*W+j;
}
}
}
void add(int x, int y, int val) {
for (int i = x; i <= W; i += lowbit(i)) {
for (int j = y; j <= W; j += lowbit(j)) {
int pos = lower_bound(h, h+cnt, i*W+j) - h;
bit[pos] += val;
}
}
}
int getsum(int x, int y) {
int sum = ;
for (int i = x; i > ; i -= lowbit(i)) {
for (int j = y; j > ; j -= lowbit(j)) {
int pos = lower_bound(h, h+cnt, i*W+j) - h;
if (h[pos] == i*W+j) sum += bit[pos]; // 没处理过的数是0 不用考虑
}
}
return sum;
} int main()
{
int n, m;
while (~scanf("%d", &n) && n) {
scanf("%d", &m);
W = n*;
cnt = ;
memset(bit, , sizeof bit);
int tx, ty;
for (int i = ; i < m; ++i) {
scanf("%d%d%d%d", &op[i], &tx, &ty, &v[i]);
x[i] = tx - ty + n;
y[i] = tx + ty;
if (op[i] == ) { // 1 means update, 2 means query
ready(x[i], y[i]);
}
}
sort(h, h+cnt);
cnt = unique(h, h+cnt) - h;
for (int i = ; i < m; ++i) {
if (op[i] == ) {
add(x[i], y[i], v[i]);
} else {
int L = max(, x[i]-v[i]);
int B = max(, y[i]-v[i]);
int R = min(W, x[i]+v[i]);
int T = min(W, y[i]+v[i]);
printf("%d\n", getsum(R,T) - getsum(L-,T)-getsum(R,B-)+getsum(L-,B-));
}
}
}
return ;
}

HDU4456-Crowd(坐标旋转+二位树状数组+离散化)的更多相关文章

  1. 【poj2155】【Matrix】二位树状数组

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=34310873 Description Given ...

  2. POJ-2155-Matrix二位树状数组应用

    题目: 一个只有0和1构成的二维平面,给你两种指令,一种是区间的更新,即0变为1,1变为0:一种是查询一个点是1还是0: 由于是二进制,所以每次更新在相应的点上加一,最后对2取余即可. 至于二维的树状 ...

  3. hdu4456 Crowd(二维树状数组)

    题意:给出一个n*n的矩阵,然后m个operation,1表示坐标(x,y)的值加z,2表示与坐标(x,y)的曼哈顿距离不超过z的点的权值和. 解题思路:将矩阵側过来45度.发现询问的时候,有效的点构 ...

  4. 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)

    BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...

  5. poj 1195:Mobile phones(二维树状数组,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14489   Accepted: 6735 De ...

  6. [POJ2155]Matrix(二维树状数组)

    题目:http://poj.org/problem?id=2155 中文题意: 给你一个初始全部为0的n*n矩阵,有如下操作 1.C x1 y1 x2 y2 把矩形(x1,y1,x2,y2)上的数全部 ...

  7. MooFest_二维树状数组

    Description Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a s ...

  8. 二维树状数组(水题) POJ1195

    前段时间遇到线段树过不了,树状数组却过了的题.(其实线段树过得了的) 回忆了下树状数组. 主要原理,还是二进制位数,每一项的和表示其为它的前((最后一位1及其后)的二进制数)和,可从二进制图来看.(用 ...

  9. 二维树状数组——SuperBrother打鼹鼠(Vijos1512)

    树状数组(BIT)是一个查询和修改复杂度都为log(n)的数据结构,主要用于查询任意两位之间的所有元素之和,其编程简单,很容易被实现.而且可以很容易地扩展到二维.让我们来看一道很裸的二维树状数组题: ...

随机推荐

  1. tcp通信:多进程共享listen socket方式

    原文链接:http://blog.csdn.net/largetalk/article/details/7939080 看tornado源码多进程(process.py)那段,发现他的多进程模型和一般 ...

  2. [Mongo] error inserting documents: BSONObj size is invalid (mongoimport mongorestore 数据备份恢复)

    解决办法如下, ./mongoimport -port 6066 -d xxx -c xxx --batchSize=10 /root/mong_data/test/xxx 原因转自 http://b ...

  3. 写给系统管理员的25个PHP安全实践

    PHP是广泛使用的开源服务端脚本语言.通过HTTP或HTTPS协议,Apache Web服务允许用户访问文件或内容.服务端脚本语言的错误配置会导致各种问题.因此,PHP应该小心使用.以下是为系统管理员 ...

  4. 1002: A+B for Input-Output Practice (II)

    问题描述: http://acm.wust.edu.cn/problem.php?id=1002&soj=0 代码实现: import java.util.Scanner; public cl ...

  5. word编辑器解码集合

    $(document).ready(function () { $(".content").each(function () { var content = $(this).htm ...

  6. Codeforces Round #271 (Div. 2)

    A. Keyboard 题意:一个人打字,可能会左偏一位,可能会右偏一位,给出一串字符,求它本来的串 和紫书的破损的键盘一样 #include<iostream> #include< ...

  7. LeetCode Factorial Trailing Zeroes (阶乘后缀零)

    题意:如标题 思路:其他文章已经写过,参考其他. class Solution { public: int trailingZeroes(int n) { <? n/: n/+trailingZ ...

  8. poj 3211 Washing Clothes

    // 题意 :夫妻两洗衣服,衣服有m种颜色,每种颜色又有若干件,每件衣服洗完需要特定的时间,要求每种颜色放在一起洗,洗完才能洗其他衣服.最后问洗完需要的最少时间// 将衣服按颜色分类 然后求出每种颜色 ...

  9. Vagrant搭建Ubuntu-JavaEE开发环境——Tomcat+JDK+MySQL+dubbo+测试

    Vagrant搭建(Tomcat8+JDK7+MySQL5+dubbo) JDK 1.下载jdk 2.解压JDK tar -xzvf jdk-7u79-linux-x64.tar.gz 3.设置环境变 ...

  10. Informatica元数据库解析

    Informatica所有的元数据信息均以数据库表的方式存到了元数据库中.当然Infa本身工具提供了很多的人性化的功能,使我们在开发时可以很方便的进行操作,但人们的需求总是万变的,需要方便的取到自己需 ...