Codeforces 1093 G. Multidimensional Queries

86 篇文章 0 订阅
24 篇文章 0 订阅

求动态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);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值