codeforces1093 G Multidimensional Queries

codeforces1093 G Multidimensional Queries

https://codeforces.com/contest/1093/problem/G

Meaning of the questions:

You n points on the k-dimensional space, the distance between two points is defined as their Manhattan distance, there are two operations:
1. the i-th point into another point B
2. Query the i-th point to the j the most distant points even points.

answer:

Direct done similar questions, we can put absolute value apart, then open the same point coordinates anti-together. Because only 5 k, so a symbol coordinate at most only 32 possible, while the distance between two points because of the absolute value of the two combined must be the largest. Therefore, simply use the tree line to maintain the range of the most value on it. Because there are 32 kinds of situations, so to establish 32 tree line.

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int bit[6]={1,2,4,8,16,32};
struct node
{
	int x,id;
	node(){};
	node(int aa,int bb):x(aa),id(bb){}
}tree[maxn<<2][33];
node Max(const node& a,const node& b)
{
	return a.x>b.x?a:b;
}
int a[maxn][10];
void pushup(int rt,int t)
{
	tree[rt][t]=Max(tree[rt<<1][t],tree[rt<<1|1][t]);
}
void update(int C,int l,int r,int L,int rt,int t)
{
	if(l==r)
	{
//		cout<<l<<" "<<rt<<endl;
		tree[rt][t]=node(C,L);
		return;
	}
	int m=(l+r)>>1; 
//	pushdown(l,r,rt);
	if(L<=m) update(C,l,m,L,rt<<1,t);
	else update(C,m+1,r,L,rt<<1|1,t);
	pushup(rt,t);
}
node query(int l,int r,int L,int R,int rt,int t)
{
	if(L<=l&&r<=R)	return tree[rt][t];
	int m=(l+r)>>1;
	node _max=node(-1e9,0);
	if(L<=m) _max=Max(_max,query(l,m,L,R,rt<<1,t));
	if(R>m) _max=Max(_max,query(m+1,r,L,R,rt<<1|1,t));
//	cout<<L<<" "<<R<<" "<<_max<<endl;
	return _max;
}
int n,k;
void build(int l,int r,int rt,int t)
{
	if(l==r)
	{
		int temp=0;
		for(int j=0;j<k;j++)
		{
			if(((t>>j)&1)==1) temp+=a[l][j]*-1;
			else temp+=a[l][j];
		}
		tree[rt][t].id=l;
		tree[rt][t].x=temp;
		return ;
	 } 
	int m=(l+r)/2;
	build(l,m,rt*2,t);
	build(m+1,r,rt*2+1,t);
	pushup(rt,t);
 } 
void change(int N)
{
	int i,j;
	for(i=0;i<bit[k];i++)
	{
		int temp=0;
		for(j=0;j<k;j++)
		{
			if(((i>>j)&1)==1) temp+=a[N][j]*-1;
			else temp+=a[N][j];
		}
		update(temp,1,n,N,1,i);
	}
}
int ret[40];
int Q(int l,int r)
{
	if(l==r) return 0;
	int _max=-1e9;
	for(int i=0;i<bit[k];i++)
	{
//		cout<<query(1,n,l,l,1,i)<<" "<<query(1,n,l+1,r,1,pow(2,k)-1-i)<<endl;
		ret[i]=query(1,n,l,r,1,i).x;
//		if(temp.id>l)	_max=max(query(1,n,l,temp.id-1,1,(bit[k]-1)^i).x+temp.x,_max);
//		if(temp.id<r)	_max=max(query(1,n,temp.id+1,r,1,(bit[k]-1)^i).x+temp.x,_max);
	}
	for(int i=0; i<(1<<k); i++){
		_max = max(_max, abs(ret[i]+ret[i^((1<<k)-1)]));
	}
	return _max;
}
int main()
{  
	#ifdef TEST
		freopen("input.txt","r",stdin);
    #endif
	int T,m,i,j;
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;i++)
		for(j=0;j<k;j++)
			scanf("%d",&a[i][j]);
	for(i=0;i<bit[k];i++) build(1,n,1,i);
	int q,o,N,l,r;
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d",&o);
		if(o==1)
		{
			scanf("%d",&N);
			for(i=0;i<k;i++)scanf("%d",&a[N][i]);
			change(N);
		}
		else
		{
			scanf("%d%d",&l,&r);
			printf("%d\n",Q(l,r));
		}
	}
}


Published 51 original articles · won praise 6 · views 6317

Guess you like

Origin blog.csdn.net/weixin_40859716/article/details/85061605