题意: 就是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();
}
}