题意:
k维平面上,会有一些点出现或者消失,求每次现存的点中,曼哈顿距离最大值。
题解:
以二维为例,对于原点而言,点(x,y)到它的曼哈顿距离为abs(x+y)或abs(x-y),到(x1,y1)的距离为abs(x+y)-abs(x1+y1)或abs(x-y)-abs(x1-y1).所以只要存下当前所有点相对原点的曼哈顿距离,对于每个点,可以用上述的方法查询其它点到它的最大曼哈顿距离。
记下每个点插入时它的最大曼哈顿距离,查询时检测是否还能取到。
//Time:5828MS
//Memory:23108K
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#define MAXN 60010
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
using namespace std;
struct _node
{
int p[5],k,to[32],top;
void dfs(int h,int sum)
{
if(h==k) to[top++]=sum;
else dfs(h+1,sum+p[h]),dfs(h+1,sum-p[h]);
}
}no[MAXN];
multiset<int> mse[32];
set<pair<int,int> >se;
bool vi[MAXN];
int cal(int h)
{
if(mse[0].size()==0||!vi[h]) return 0;
int ret=0;
for(int i=0,j=1<<no[h].k;i<j;++i)
ret=max(ret,*(mse[i].rbegin())-no[h].to[i]);
return ret;
}
void add(int h)
{
for(int i=0,j=1<<no[h].k;i<j;++i)
mse[i].insert(no[h].to[i]);
}
void erase(int h)
{
for(int i=0,j=1<<no[h].k;i<j;++i)
mse[i].erase(mse[i].find(no[h].to[i]));
}
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int n,k,ans,tmp;
while(scanf("%d%d",&n,&k)==2)
{
memset(vi,0,sizeof(vi));
se.clear();
for(int i=0,j=1<<k;i<j;++i) mse[i].clear();
int od;
for(int i=0;i<n;++i)
{
scanf("%d",&od);
ans=0;
if(od==0)
{
no[i].k=k;
for(int j=0;j<k;++j) scanf("%d",&no[i].p[j]);
no[i].top=0;
no[i].dfs(0,0);
vi[i]=1;
ans=cal(i);
add(i);
if(ans>0)
se.insert(MP(ans,i));
ans=0;
}
else
{
scanf("%d",&tmp);
vi[tmp-1]=0;
multiset<int>::iterator ite;
// for(ite=mse[0].begin();ite!=mse[0].end();++ite) printf("%d ",*ite);
// printf("\n");
erase(tmp-1);
// for(ite=mse[0].begin();ite!=mse[0].end();++ite) printf("%d ",*ite);
// printf("\n");
}
while(se.size())
{
int tt=cal(se.rbegin()->SE);
if(tt==se.rbegin()->FI)
break;
int tmph=se.rbegin()->SE;
se.erase(*se.rbegin());
if(tt>0) se.insert(MP(tt,tmph));
}
if(se.size()) ans=se.rbegin()->FI;
printf("%d\n",ans);
}
}
return 0;
}