思路:这题我是看了题目后,上百度搜了一下才知道还有求最大曼哈顿距离的方法。直接把代码copy过来,研读一下,知道了代码实现机制,自然就很容易想到用优先队列来维护每种状态下的xi,yi之和的最大值最小值,以及其属于哪个点。那么对于删点操作只需要标记为不存在就可以了。在队列出队时,若队顶元素不存在,就出队。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #include <cstdlib> using namespace std; const int Maxn=100005; const int inf=0x7fffffff; struct Que{ int Val,id; int operator > (const Que &temp) const { return Val<temp.Val; } int operator < (const Que &temp) const { return Val>temp.Val; } }; priority_queue <Que> Min[40]; priority_queue < Que, vector<Que>, greater<Que> > Max[40]; int x[6],vi[Maxn]; void init() { memset(vi,0,sizeof(vi)); int i; for(i=0;i<=35;i++) { while(!Min[i].empty()) Min[i].pop(); while(!Max[i].empty()) Max[i].pop(); } } int main(){ int i, j,od,tmp,dem,k,q,t,s; while(scanf("%d%d", &q,&dem)!=EOF){ init(); memset(vi,0,sizeof(vi)); tmp=1<<dem; Que p; for(i=1;i<=q;i++) { scanf("%d",&od); if(od==0) { for(j=0;j<dem;j++) scanf("%d",&x[j]); for(j=0; j<tmp; j++){ t=j;s=0; for(k=0; k<dem; k++){ if(t&1) s+=x[k]; else s-=x[k]; t>>=1; } p.id=i; p.Val=s; Min[j].push(p); Max[j].push(p); } } else { int x; scanf("%d",&x); vi[x]=1; } Que l,r; int ans=0; for(j=0;j<tmp;j++){ l=Min[j].top(); r=Max[j].top(); while(vi[l.id]) { Min[j].pop(); l=Min[j].top(); } while(vi[r.id]) { Max[j].pop(); r=Max[j].top(); } ans=max(ans,r.Val-l.Val); } printf("%d ",ans); } } return 0; }