版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/85239229
求动态k维曼哈顿最大距离。这个很板。
线段树这个东西和FFT,FWT之类的一样,找位置反倒是最耗时间的,所以要把32维压起来一起下放上传。。。。跑的飞快
AC Code:
#include<algorithm>
#include<cctype>
#include<cstring>
#define maxn 800005
#define inf 0x3f3f3f3f
#define lc now<<1
#define rc now<<1|1
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
inline void read(int &res)
{ char ch;bool flag=0;
for(;!isdigit(ch=getc());)if(ch=='-') flag=1;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
(flag) && (res = -res);
}
int n,x[maxn][5],k;
int Max[maxn][32],Min[maxn][32];
void Insert(int now,int l,int r,int pos,int *a)
{
if(l > pos || r < pos) return;
if(l==r){ for(int i=0;i<(1<<k);i++) Min[now][i]=Max[now][i]=a[i]; return;}
int mid = (l+r) >> 1;
Insert(lc,l,mid,pos,a),Insert(rc,mid+1,r,pos,a);
for(int i=0;i<(1<<k);i++)
Min[now][i]=min(Min[lc][i],Min[rc][i]),
Max[now][i]=max(Max[lc][i],Max[rc][i]);
}
void Qmin(int now,int l,int r,int ql,int qr,int *ret)
{
if(l > qr || r < ql) return;
if(ql <= l && r <= qr)
{ for(int i=0;i<(1<<k);i++) ret[i]=min(ret[i],Min[now][i]);return;}
int mid = (l+r) >> 1;
Qmin(lc,l,mid,ql,qr,ret),Qmin(rc,mid+1,r,ql,qr,ret);
}
void Qmax(int now,int l,int r,int ql,int qr,int *ret)
{
if(l > qr || r < ql) return;
if(ql <= l && r <= qr)
{ for(int i=0;i<(1<<k);i++) ret[i]=max(ret[i],Max[now][i]);return;}
int mid = (l+r) >> 1;
Qmax(lc,l,mid,ql,qr,ret),Qmax(rc,mid+1,r,ql,qr,ret);
}
int calc(int sta,int loc)
{
int ret = 0;
for(int i=0;i<k;i++)
if((sta>>i) & 1)
ret += x[loc][i];
else
ret -= x[loc][i];
return ret;
}
int sta[2][32];
int main()
{
read(n),read(k);
for(int i=1;i<=n;i++)
{
for(int j=0;j<k;j++) read(x[i][j]);
for(int p=0;p<(1<<k);p++) sta[0][p] = calc(p,i);
Insert(1,1,n,i,sta[0]);
}
int q;
for(read(q);q--;)
{
int op;read(op);
if(op == 1)
{
int i;read(i);
for(int j=0;j<k;j++) read(x[i][j]);
for(int p=0;p<(1<<k);p++) sta[0][p] = calc(p,i);
Insert(1,1,n,i,sta[0]);
}
else
{
int l,r;read(l),read(r);
int ans = 0;
memset(sta[0],-0x3f,sizeof sta[0]);
memset(sta[1],0x3f,sizeof sta[1]);
Qmax(1,1,n,l,r,sta[0]),Qmin(1,1,n,l,r,sta[1]);
for(int i=0;i<(1<<k);i++) ans = max(sta[0][i] - sta[1][i] , ans);
printf("%d\n",ans);
}
}
}