1. 程式人生 > >Codeforces 1093 G. Multidimensional Queries

Codeforces 1093 G. Multidimensional Queries

求動態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);
		}
	}
}