http://acm.hdu.edu.cn/showproblem.php?pid=4666
动态求最远曼哈顿距离 线段树维护区间最值就好 但是k维空间会有2^k种情况 只能离线每一种情况 最后么一个位置在所有情况中取最值 如果在线求的话 只能建2^m棵线段树 浪费太多没有必要的空间
#include <bits/stdc++.h>
using namespace std;
const int N=0x3f3f3f3f;
struct node0
{
int tp;
int id;
int x[5];
};
struct node1
{
int l;
int r;
int flag;
int maxx;
int minn;
};
node0 order[60010];
node1 tree[240010];
int pre[50],ans[60010];
int n,m;
void init()
{
int i;
pre[0]=1;
for(i=1;i<=30;i++) pre[i]=2*pre[i-1];
}
void pushup(int cur)
{
tree[cur].flag=tree[2*cur].flag|tree[2*cur].flag;
tree[cur].maxx=max(tree[2*cur].maxx,tree[2*cur+1].maxx);
tree[cur].minn=min(tree[2*cur].minn,tree[2*cur+1].minn);
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].flag=0;
tree[cur].maxx=-N;
tree[cur].minn=N;
if(l==r) return;
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
}
void updateI(int tar,int val,int cur)
{
if(tree[cur].l==tree[cur].r)
{
tree[cur].flag=1;
tree[cur].maxx=val;
tree[cur].minn=val;
return;
}
if(tar<=tree[2*cur].r) updateI(tar,val,2*cur);
else updateI(tar,val,2*cur+1);
pushup(cur);
}
void updateII(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
tree[cur].flag=0;
tree[cur].maxx=-N;
tree[cur].minn=N;
return;
}
if(tar<=tree[2*cur].r) updateII(tar,2*cur);
else updateII(tar,2*cur+1);
pushup(cur);
}
int main()
{
int i,j,k,val;
init();
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d",&order[i].tp);
if(order[i].tp==0) for(j=0;j<m;j++) scanf("%d",&order[i].x[j]);
else scanf("%d",&order[i].id);
}
memset(ans,0,sizeof(ans));
for(j=0;j<pre[m];j++)
{
build(1,n,1);
for(i=1;i<=n;i++)
{
if(order[i].tp==0)
{
val=0;
for(k=0;k<m;k++)
{
if(j&pre[k]) val+=order[i].x[k];
else val-=order[i].x[k];
}
updateI(i,val,1);
}
else updateII(order[i].id,1);
ans[i]=max(ans[i],tree[1].maxx-tree[1].minn);
}
}
for(i=1;i<=n;i++) printf("%d\n",ans[i]);
}
return 0;
}