@

题意:

在三维空间\((n\times m\times h\le 100000)\)内,有\(q(q\le 100000)\)次操作。操作\(1\):添加一个点进入空间;操作\(2\):查询最近点对。


分析:

比赛时听G黄说完题意感觉看似好像裸题,一道在二维平面上操作完全的题:BZOJ2716

那么KD-Tree还是四维偏序问题呢?(原来都不是。。出题人放出豪言:KD-Tree想过?不可能的

解法1:三维BIT - 862ms

  • 把曼哈顿距离的绝对值去掉后,共有8种情况。
  • 用8个BIT把每个点拆掉绝对值后的8种贡献记录一下即可。
  • 比如这种情况:这个点在其他点的左后下方时:\(len=|x1-x2|+|y1-y2|+|z1-z2|=(x1+y1+z1)-(x2+y2+z2)\)。就\(update(x2,y2,z2)\),值为\(-(x2+y2+z2)\)。以此类推。
  • 我们知道对于两个确定的点,他们相对位置也确定了,显然\(p2\)在用\(p1\)的正确相对位置的\(query()\)求出来的距离一定是最小的。这种做法正确性十分显然。然后BIT常数非常小,很容易过去的。

解法2:定期重构+BFS - 86ms (ps:好像是最快的

定期重构这应该是一个很常见的套路的吧?有些分块好像经常有这种操作?

  • 对三维空间维护一个值\(dis[i]\),表示离当前点\(i\)位置的最近点距离。
  • 当新加入的点的数量小于阈值MX时,暴力比对这些新加入的点。
  • 当达到了阈值MX时,就用这些新加入的点松弛我们的\(dis[]\)即可。
  • 代码挺好懂的。。。

    Code1
const int MXN = 3e3 + 7;
const int MXE = 2e6 + 7;
typedef vector<int> VI;
typedef vector<VI > VVI;
typedef vector<VVI > VVVI;
//mat c(a.size(), vec(b[0].size(), 0));
//VVVI bit(n+1,VVI(m+1, VI(h+1, INF)));
int n, m, h, q;
struct BIT {
int n, m, h;
vector<vector<vector<int> > > bit;
void init(int _n, int _m, int _h) {
n = _n, m = _m, h = _h;
bit = VVVI(n+1,VVI(m+1, VI(h+1, INF)));
}
void update(int _x, int _y, int _z, int v) {
for(int x = _x; x <= n; x += lowbit(x)) {
for(int y = _y; y <= m; y += lowbit(y)) {
for(int z = _z; z <= h; z += lowbit(z)) {
bit[x][y][z] = sml(bit[x][y][z], v);
}
}
}
}
int query(int _x, int _y, int _z) {
int res = INF;
for(int x = _x; x > 0; x -= lowbit(x)) {
for(int y = _y; y > 0; y -= lowbit(y)) {
for(int z = _z; z > 0; z -= lowbit(z)) {
res = sml(bit[x][y][z], res);
}
}
}
return res;
}
}bit[8];
int main() {
#ifndef ONLINE_JUDGE
freopen("/home/cwolf9/CLionProjects/ccc/in.txt", "r", stdin);
// freopen("/home/cwolf9/CLionProjects/ccc/out.txt", "w", stdout);
#endif
n = read(), m = read(), h = read(), q = read();
int opt, x, y, z, ans;
for(int i = 0; i < 8; ++i) bit[i].init(n, m, h);
while(q --) {
opt = read(), x = read(), y = read(), z = read();
if(opt == 1) {
for(int i = 0; i < 8; ++i) {
int v = (i&1?x:-x) + ((i>>1)&1?y:-y) + ((i>>2)&1?z:-z);
// debug(i, i&1?x:n+1-x, (i>>1)&1?y:m+1-y, (i>>2)&1?z:h+1-z, v)
// debug(i&1?n+1-x:x, (i>>1)&1?m+1-y:y, (i>>2)&1?h+1-z:z)
bit[i].update(i&1?n+1-x:x, (i>>1)&1?m+1-y:y, (i>>2)&1?h+1-z:z, v);
}
}else {
ans = INF;
for(int i = 0; i < 8; ++i) {
int v = (i&1?-x:x) + ((i>>1)&1?-y:y) + ((i>>2)&1?-z:z);
// debug(x, y, z)
// debug(opt, i&1?n+1-x:x, (i>>1)&1?m+1-y:y, (i>>2)&1?h+1-z:z)
ans = sml(ans, v + bit[i].query(i&1?n+1-x:x, (i>>1)&1?m+1-y:y, (i>>2)&1?h+1-z:z));
}
printf("%d\n", ans);
}
}
return 0;
}

Code2

const int MXN = 1e6 + 7;
const int MXE = 2e6 + 7;
typedef vector<int> VI;
typedef vector<VI > VVI;
typedef vector<VVI > VVVI;
//mat c(a.size(), vec(b[0].size(), 0));
int n, m, h, q;
const int MX = 1000;
VI X, Y, Z;
int dis[MXN];
namespace lh {
int hash(int x, int y, int z) {
return x * m * h + y * h + z;
}
}
struct lp {
int x, y, z;
};
int dir[6][3] = {1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1};
void rebuild() {
queue<lp> Q;
for(int i = 0; i < SZ(X); ++i) {
dis[lh::hash(X[i], Y[i], Z[i])] = 0;
Q.push({X[i], Y[i], Z[i]});
}
while(!Q.empty()) {
lp A = Q.front(); Q.pop();
for(int i = 0; i < 6; ++i) {
int px = A.x + dir[i][0], py = A.y + dir[i][1], pz = A.z + dir[i][2];
if(px < 0 || py < 0 || pz < 0 || px >= n || py >= m || pz >= h || dis[lh::hash(px, py, pz)] <= dis[lh::hash(A.x, A.y, A.z)] + 1) continue;
dis[lh::hash(px, py, pz)] = dis[lh::hash(A.x, A.y, A.z)] + 1;
Q.push(lp{px, py, pz});
}
}
X.clear(), Y.clear(), Z.clear();
}
int main() {
#ifndef ONLINE_JUDGE
freopen("/home/cwolf9/CLionProjects/ccc/in.txt", "r", stdin);
// freopen("/home/cwolf9/CLionProjects/ccc/out.txt", "w", stdout);
#endif
n = read(), m = read(), h = read(), q = read();
int opt, x, y, z, ans;
clr(dis, 0x3f);
while(q --) {
opt = read(), x = read(), y = read(), z = read();
-- x, -- y, -- z;
if(opt == 1) {
X.eb(x), Y.eb(y), Z.eb(z);
}else {
ans = dis[lh::hash(x, y, z)];
for(int i = 0; i < SZ(X); ++i) ans = sml(ans, abs(x - X[i]) + abs(y - Y[i]) + abs(z - Z[i]));
printf("%d\n", ans);
}
if(1 || SZ(X) == MX) rebuild();
}
return 0;
}

2019牛客第八场多校 D_Distance 三维BIT或定期重建套路的更多相关文章

  1. 2019牛客第八场多校 E_Explorer 可撤销并查集(栈)+线段树

    目录 题意: 分析: @(2019牛客暑期多校训练营(第八场)E_Explorer) 题意: 链接 题目类似:CF366D,Gym101652T 本题给你\(n(100000)\)个点\(m(1000 ...

  2. 牛客第三场多校 E Sort String

    链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...

  3. 牛客第三场多校 H Diff-prime Pairs

    链接:https://www.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy has solved lots of problem involving calcul ...

  4. 牛客第五场多校 J plan 思维

    链接:https://www.nowcoder.com/acm/contest/143/J来源:牛客网 There are n students going to travel. And hotel ...

  5. 牛客第五场多校 A gpa 分数规划(模板)

    链接:https://www.nowcoder.com/acm/contest/143/A来源:牛客网 Kanade selected n courses in the university. The ...

  6. PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)

    题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...

  7. 牛客第八场 C-counting paths 树形dp计数

    题目地址 题意 给你一颗树 初始点颜色全部为白色 对于每一个满足要求一的点集s f(s)的定义为先把点集内的点染黑 满足要求二的路径集合数量 要求一为两两黑点之间不能出现白色的点 要求二为将这个路径集 ...

  8. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  9. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

随机推荐

  1. A Bug's Life - poj2492

    Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Descr ...

  2. [POJ3735]Training little cats

    题目:Training little cats 链接:http://poj.org/problem?id=3735 分析: 1)将操作用矩阵表示出来,然后快速幂优化. 2)初始矩阵:$ \left[ ...

  3. [CSP-S模拟测试]:Walk(BFS+建边)

    题目描述 在比特镇一共有$n$个街区,编号依次为$1$到$n$,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了$m$条单向道路之外,每个街区还有一个编码${val}_i$,不同街区可 ...

  4. python and 用法

    >>> 1 and [] and [1] [] >>> 1 and [2] and [1] [1] >>> 0 and [1] and [2] 0

  5. idea中git回退远程仓库版本

    工作中遇到,代码已提交并已提交到远程仓库,现需要回退到之前版本,记录如下: 记录当前版本的版本号和需要回退到版本的版本号. current version:85e7f32dfe421c5892a4e2 ...

  6. jmeter添加自定义扩展函数之小写转换大写

    1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...

  7. MAC使用命令行打包出ipa包-通过xcodeproj

    参考 : https://www.jianshu.com/p/32af2f71b4e5--老了,里面的一些命令现在都没有了,但可以借鉴思路 https://www.jianshu.com/p/004c ...

  8. 斯坦福【概率与统计】课程笔记(五):EDA | 箱线图

    介绍箱线图之前,需要先介绍若干个其需要的术语 min:整个样本的最小值 max:整个样本的最大值 Range:即整个样本的取值范围,Range = max - min Inter-Quartile R ...

  9. HBaseRegionServer宕机数据恢复

    本文由 网易云 发布 作者:范欣欣 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 众所周知,HBase默认适用于写多读少的应用,正是依赖于它相当出色的写入性能:一个100台RS的集群可以轻松地 ...

  10. 2019杭电多校第⑨场B Rikka with Cake (主席树,离散化)

    题意: 给定一块n*m的矩形区域,在区域内有若干点,每个顶点发出一条射线,有上下左右四个方向,问矩形被分成了几个区域? 思路: 稍加观察和枚举可以发现,区域数量=射线交点数+1(可以用欧拉定理验证,但 ...