献上博文一篇http://hi.baidu.com/byplane747/item/53ca46c159e654bc0d0a7b8d
设维度为k,维护(1<<k)个优先队列,用来保存0~(1<<k)-1 种状态(状态压缩),设状态1为“+”,状态0为“0”。
对于命令0,求出每个状态j的值,并与优先队列(s-j)的top()值相加,计算最大值。
对于命令1,标记消除的点,对每个队列pop()到存在的点。重新算一遍最大值。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 #define rep(i,a,b) for(int i=a;i<=b;i++) 6 #define clr(a,m) memset(a,m,sizeof(a)) 7 using namespace std; 8 9 const int MAXN=666666; 10 11 struct Q{ 12 int t,id; 13 Q(){} 14 Q(int _t,int _id):t(_t),id(_id){} 15 bool operator < (const Q &tmp) const{ 16 return t<tmp.t; 17 } 18 }; 19 20 priority_queue<Q>q[1<<5]; 21 int vis[MAXN]; 22 int a[5],b[1<<5]; 23 24 int main() 25 { 26 int n,cnt; 27 while(~scanf("%d%d",&n,&cnt)) 28 { 29 int op,s=(1<<cnt)-1; 30 int ans=0; 31 clr(vis,0); 32 rep(i,0,s) 33 while(!q[i].empty()) 34 q[i].pop(); 35 rep(i,1,n){ 36 scanf("%d",&op); 37 38 if(!op){ 39 rep(j,0,cnt-1) 40 scanf("%d",&a[j]); 41 rep(j,0,s){ 42 int ad=0; 43 rep(k,0,cnt-1){ 44 if(j&(1<<k)) 45 ad+=a[k]; 46 else 47 ad-=a[k]; 48 } 49 if(!q[s-j].empty()){ 50 ans=max(ans,ad+q[s-j].top().t); 51 } 52 b[j]=ad; 53 } 54 rep(j,0,s) 55 q[j].push(Q(b[j],i)); 56 }else { 57 int pos; 58 scanf("%d",&pos); 59 vis[pos]=1; 60 rep(j,0,s){ 61 while(!q[j].empty()&&vis[q[j].top().id]) 62 q[j].pop(); 63 } 64 ans=0; 65 rep(j,0,s) 66 if(!q[j].empty()&&!q[s-j].empty()) 67 ans=max(ans,q[j].top().t+q[s-j].top().t); 68 } 69 printf("%d ",ans); 70 } 71 } 72 return 0; 73 }