zoukankan      html  css  js  c++  java
  • [CF1093G]Multidimensional Queries

    [CF1093G]Multidimensional Queries

    题目大意:

    (k(kle5))维空间中有(n(nle2 imes10^5))个点。(m)次操作,操作包含一下两种:

    1. 将第(i)个点改为((b_1,b_2,ldots,b_k))
    2. 询问编号在([l,r])内的所有点对中,曼哈顿距离的最大值。

    思路:

    枚举每一维坐标对答案的贡献的符号是正还是负,总共(2^{k-1})种情况。每种情况用线段树维护最大/最小值。询问时在每棵线段树上查询区间最大值-区间最小值,对所有的情况取最大值即可。

    时间复杂度(mathcal O(2^knlog n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<climits>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	register bool neg=false;
    	while(!isdigit(ch=getchar())) neg|=ch=='-';
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return neg?-x:x;
    }
    const int N=2e5+1,K=5;
    int n,k,a[K];
    class SegmentTree {
    	#define _left <<1
    	#define _right <<1|1
    	#define mid ((b+e)>>1)
    	private:
    		int max[N<<2],min[N<<2];
    		void push_up(const int &p) {
    			max[p]=std::max(max[p _left],max[p _right]);
    			min[p]=std::min(min[p _left],min[p _right]);
    		}
    	public:
    		void modify(int p,const int &y) {
    			max[p]=min[p]=y;
    			while(p!=1) {
    				p>>=1;
    				push_up(p);
    			}
    		}
    		int qmax(const int &p,const int &b,const int &e,const int &l,const int &r) const {
    			if(b==l&&e==r) return max[p];
    			int ret=INT_MIN;
    			if(l<=mid) ret=std::max(ret,qmax(p _left,b,mid,l,std::min(mid,r)));
    			if(r>mid) ret=std::max(ret,qmax(p _right,mid+1,e,std::max(mid+1,l),r));
    			return ret;
    		}
    		int qmin(const int &p,const int &b,const int &e,const int &l,const int &r) const {
    			if(b==l&&e==r) return min[p];
    			int ret=INT_MAX;
    			if(l<=mid) ret=std::min(ret,qmin(p _left,b,mid,l,std::min(mid,r)));
    			if(r>mid) ret=std::min(ret,qmin(p _right,mid+1,e,std::max(mid+1,l),r));
    			return ret;
    		}
    	#undef _left
    	#undef _right
    	#undef mid
    };
    SegmentTree t[1<<K];
    inline int query(const int &s,const int &l,const int &r) {
    	return t[s].qmax(1,1,n,l,r)-t[s].qmin(1,1,n,l,r);
    }
    inline int find(const int &x) {
    	int b=1,e=n,p=1;
    	while(b<e) {
    		const int mid=(b+e)>>1;
    		if(x<=mid) {
    			e=mid;
    			p=p<<1;
    		} else {
    			b=mid+1;
    			p=p<<1|1;
    		}
    	}
    	return p;
    }
    int main() {
    	n=getint(),k=getint();
    	for(register int i=1;i<=n;i++) {
    		for(register int i=0;i<k;i++) a[i]=getint();
    		const int pos=find(i);
    		for(register int s=0;s<1<<(k-1);s++) {
    			int val=0;
    			for(register int j=0;j<k;j++) {
    				val+=a[j]*(s>>j&1?:-1);
    			}
    			t[s].modify(pos,val);
    		}
    	}
    	const int q=getint();
    	for(register int i=0;i<q;i++) {
    		const int opt=getint();
    		if(opt==1) {
    			const int x=getint(),pos=find(x);
    			for(register int i=0;i<k;i++) a[i]=getint();
    			for(register int s=0;s<1<<(k-1);s++) {
    				int val=0;
    				for(register int j=0;j<k;j++) {
    					val+=a[j]*(s>>j&1?:-1);
    				}
    				t[s].modify(pos,val);
    			}
    		}
    		if(opt==2) {
    			const int l=getint(),r=getint();
    			int ans=0;
    			for(register int s=0;s<1<<(k-1);s++) {
    				ans=std::max(ans,query(s,l,r));
    			}
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Linux守护进程的编程实现
    QUIC简单介绍
    oracle10G/11G官方下载地址集合 直接迅雷下载
    Linux 解决文件删除,但并没有改变磁盘可用性
    开始使用正则表达式
    Codeforces 442C Artem and Array(stack+贪婪)
    Drop dual
    ios结构体httpPost头结构
    一个人ACM(我们赶上了ACM)
    Linux svnserver存储路径和文件的详细解释
  • 原文地址:https://www.cnblogs.com/skylee03/p/10397307.html
Copyright © 2011-2022 走看看