思路: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 " , getAns()); } } return 0; }