思路:n维空间计算最远的曼哈顿距离
分析:
1 这一题和poj2926很像,但是poj那题是静态的而这边则是动态的,对于静态的话我们知道只要去求出2^n状态下的最大值和最小值,然后求最大的差值即为ans
2 但是对于动态的来说我们需要去维护每一个状态的最大值和最小值,因此我们利用multiset来保存每一个状态下的所有的值,因为multiset是自动排序那么我们就可以很好的求出最大值和最小值
3 注意这边保存点不能够用struct要用数组,因为每次保存在结构体里面的话回去调用构造函数时间开销很大
代码:
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 5;
const int MAXN = 60010;
int n , k , pos;
int numId[MAXN];
int mat[MAXN][N];
multiset<int> mst[1<<N];
void init(){
pos = 0;
for(int i = 0 ; i < (1<<k) ; i++)
mst[i].clear();
}
int getSum(int id , int s){
int sum = 0;
for(int i = 0 ; i < k ; i++){
if(s&(1<<i))
sum += mat[id][i];
else
sum -= mat[id][i];
}
return sum;
}
void add(){
for(int i = 0 ; i < (1<<k) ; i++){
int sum = getSum(pos , i);
mst[i].insert(sum);
}
}
void remove(int id){
for(int i = 0 ; i < (1<<k) ; i++){
int sum = getSum(id , i);
multiset<int>::iterator it;
it = mst[i].find(sum);
mst[i].erase(it);
}
}
int getAns(){
multiset<int>::iterator it;
int tmp;
int ans = 0;
for(int i = 0 ; i < (1<<k) ; i++){
it = mst[i].end();
it--;
tmp = *it;
it = mst[i].begin();
tmp -= *it;
ans = max(ans , tmp);
}
return ans;
}
int main(){
int mark , x , y;
while(scanf("%d%d" , &n , &k) != EOF){
init();
for(int i = 0 ; i < n ; i++){
scanf("%d" , &mark);
if(mark == 0){
numId[i+1] = pos;
for(int j = 0 ; j < k ; j++)
scanf("%d" , &mat[pos][j]);
add();
pos++;
}
else{
scanf("%d" , &x);
remove(numId[x]);
}
printf("%d\n" , getAns());
}
}
return 0;
}