zoukankan      html  css  js  c++  java
  • D-Distance_2019牛客暑期多校训练营(第八场)

    题目链接

    Distance

    题意

    1<=nmh,q<=1e5
    q个操作

    • 1 x y z往坐标里加入一个点
    • 2 x y z查询距离该点最近的点的距离(曼哈顿距离)

    题解

    做法一

    将要插入的点保存在一个队列中,当队列中的点数达到一个阈值就把队列中所有点取出,暴力的bfs一次把答案记录在(dis[getid(x,y,z)])中表示距离点((x,y,z))最近的点的距离,查询的时候就取暴力的计算查询点和队列中每个点的距离,再和已经插入的点也就是dis数组取最小值,当阈值取(sqrt{nmh})时复杂度为(O(frac{qnmh}E + qE) = O(nmh + qsqrt{nmh}))

    做法二

    将距离公式(|x_0-x_i| + |y_0-y_i| + |z_0-z_i|)的绝对值拆开有八种情况(pm(x_0-x_i) pm (y_0-y_i) pm (z_0-z_i))
    这八种情况的最大值就是真正的距离,我们将插入的点分成((pm x, pm y, pm z))八种情况分别插入八个树状数组,树状数组维护(x_i <= x, y_i <= y, z_i <= z的x+y+z)的最大值,目的是为了把求最近点的距离转换成求((x+y+z-x_i-y_i-z_i))的最小值,查询的时候对八个树状数组答案取min就行了

    代码

    做法一

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
      
    const int mx = 1e5+5;
    const int mod = 998244353;
    const int INF = 0x3f3f3f3f;
    const int dir[6][3] = {{0,0,1}, {0,0,-1}, {0,1,0}, {0,-1,0}, {1,0,0}, {-1,0,0}};
    int dis[mx];
    int n, m, h, q;
    struct node {
        int x, y, z, step;
    };
     
    vector <node> v;
    queue <node> Q;
     
    int getid(int x, int y, int z) {
        return (x-1)*m*h + (y-1)*h + z;
    }
     
    int getdis(int x, int y, int z, int a, int b, int c) {
        return abs(x-a) + abs(y-b) + abs(z-c);
    }
     
    int main() {
        for (int i = 0; i < mx; i++) dis[i] = INF;
         
        scanf("%d%d%d%d", &n, &m, &h, &q);
        int sq = sqrt(n*m*h)    ;
        while (q--) {
            int op, x, y, z;
            scanf("%d%d%d%d", &op, &x, &y, &z);
            if (op == 1) {
                v.push_back({x, y, z, 0});
                if (v.size() == sq) {
                    for (int i = 0; i < v.size(); i++) {
                        Q.push(v[i]);
                        dis[getid(v[i].x, v[i].y, v[i].z)] = 0;
                    }
                    v.clear();
                    while (!Q.empty()) {
                        node now = Q.front();
                        node next;
                        Q.pop();
                        for (int i = 0; i < 6; i++) {
                            next.x = now.x + dir[i][0];
                            next.y = now.y + dir[i][1];
                            next.z = now.z + dir[i][2];
                            if (next.x < 1 || next.x > n || next.y < 1 || next.y > m || next.z < 1 || next.z > h) continue;
                            next.step = now.step + 1;
                            if (next.step < dis[getid(next.x, next.y, next.z)]) {
                                dis[getid(next.x, next.y, next.z)] = next.step;
                                Q.push(next);
                            }
                        }
                    }
                }
            } else {
                int ans = dis[getid(x, y, z)];
                for (int i = 0; i < v.size(); i++) {
                    ans = min(ans, getdis(x, y, z, v[i].x, v[i].y, v[i].z));
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    

    做法二

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    const int mx = 8e5+5;
    const int mod = 998244353;
    const int INF = 0x3f3f3f3f;
    const int dir[8][3] = {{1,1,1}, {1,1,-1}, {1,-1,1}, {1,-1,-1}, {-1,1,1}, {-1,1,-1}, {-1,-1,1}, {-1,-1,-1}};
    int dis[mx];
    int n, m, h, q;
    
    int getid(int x, int y, int z) {
        return (x-1)*m*h + (y-1)*h + z;
    }
    
    struct Bit {
        int a[mx];
        int lowbit(int x) {
            return x & -x;
        }
        void update(int x, int y, int z) {
            if (x < 0) x += n;
            if (y < 0) y += m;
            if (z < 0) z += h;
            for (int i = x; i <= n; i+=lowbit(i))
                for (int j = y; j <= m; j+=lowbit(j))
                    for (int k = z; k <= h; k+=lowbit(k))
                        a[getid(i,j,k)] = max(a[getid(i,j,k)], x+y+z);
        }
    
        int query(int x, int y, int z) {
            if (x < 0) x += n;
            if (y < 0) y += m;
            if (z < 0) z += h;
            int ans = 0;
            for (int i = x; i > 0; i-=lowbit(i))
                for (int j = y; j > 0; j-=lowbit(j))
                    for (int k = z; k > 0; k-=lowbit(k))
                        ans = max(a[getid(i,j,k)], ans);
            if (ans == 0) return INF;
            else return x+y+z-ans;
        }
    }bit[8];
    
    int main() {   
        scanf("%d%d%d%d", &n, &m, &h, &q);
        n++; m++; h++;
        while (q--) {
            int op, x, y, z;
            scanf("%d%d%d%d", &op, &x, &y, &z);
            if (op == 1) {
                for (int i = 0; i < 8; i++) {
                    bit[i].update(x*dir[i][0], y*dir[i][1], z*dir[i][2]);
                }
            } else {
                int ans = INF;
                for (int i = 0; i < 8; i++) ans = min(ans, bit[i].query(x*dir[i][0], y*dir[i][1], z*dir[i][2]));
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    Java环境变量的配置
    Vim的使用
    codeforces round506(div3)A. Many Equal Substrings
    codeforces round 531(div3) D. Balanced Ternary String
    codeforces Manthan, Codefest 18 (rated, Div. 1 + Div. 2) D. Valid BFS
    codeforces codefest18(div1+div2) B. Reach Median
    D. Sum in the tree codeforces round#530(div2)
    codeforces round 508(div2) D. Slime
    codeforces goodbye 2018 C. New Year and the Sphere Transmission D. New Year and the Permutation Concatenation
    C. Classy Numbers cf edu round50
  • 原文地址:https://www.cnblogs.com/bpdwn-cnblogs/p/11395483.html
Copyright © 2011-2022 走看看