HDU - 4666 Hyperspace 【动态多维度求最大曼哈顿距离】

版权声明:本文为博主原创文章,喜欢就点个赞吧 https://blog.csdn.net/Anxdada/article/details/81985361

传送门

题意: 就是0表示加入一个点, 1表示删除一个点, 后面跟第几个输入的标号. 每次输出当前有的点的最大曼哈顿距离

思路: 多个点求最大曼哈顿距离怎么求就不说了, 主要是要怎么删除, 那么我们就用(1 << k)个multiset来存每个状态的每个值, 然后每次求每个set的最大值减最小值求一个最优即可. 然后删除也直接先find然后再erase即可, 注意存下每一个的点值, 方便删除, 因为用的multiset. 所以要删迭代器, 不能直接删除数.

AC Code

const int maxn = 6e4 + 5;
int n, k, all;
ll a[maxn][8];
multiset<ll>mst[35];
void solve() {
    while(~scanf("%d%d", &n, &k)) {
        ll ans = 0; all = (1<<k);
        for (int i = 1 ; i <= n ; i ++) {
            int op; scanf("%d", &op);
            if (op) {
                int x; scanf("%d", &x);
                for (int s = 0 ; s < all ; s ++) {
                    ll t = 0;
                    for (int j = 0 ; j < k ; j++) { // 二进制位了好写, 还是从0开始存吧
                        if ((1<<j) & s) t += a[x][j];
                        else t -= a[x][j];
                    }
                    mst[s].erase(mst[s].find(t));
                }
            }
            else {
                for (int j = 0 ; j < k ; j ++) scanf("%lld", &a[i][j]);
                for (int s = 0 ; s < all ; s ++) {
                    ll t = 0;
                    for (int j = 0 ; j < k ; j++) {
                        if ((1<<j) & s) t += a[i][j];
                        else t -= a[i][j];
                    }
                    mst[s].insert(t);
                }
            }
            ll ans = 0;
            for (int s = 0 ; s < all ; s ++) {
                auto it1 = mst[s].begin();
                auto it2 = mst[s].end(); -- it2;
                ans = max(ans, *it2 - *it1);
            }
            printf("%lld\n", ans);
        }
        for (int i = 0 ; i < all ; i ++) mst[i].clear();
    }
}

猜你喜欢

转载自blog.csdn.net/Anxdada/article/details/81985361