zoukankan      html  css  js  c++  java
  • [CF1093G]Multidimensional Queries:线段树

    分析

    非常有趣的一道题。

    式子中的绝对值很难处理,但是我们发现:

    [sum_{i=1}^{k}|a_{x,i}-a_{y,i}|=sum_{i=1}^{k}max(a_{x,i}-a_{y,i},a_{y,i}-a_{x,i})=max{sum_{i=1}^{k}c_ia_{x,i}-sum_{i=1}^{k}c_ia_{y,i}} ]

    其中(c)是所有长度为(k)的只由(-1)(1)组成的数列,共有(2^k)种。

    所以我们可以对于每一种(c)维护一棵支持单点修改,查询区间最小值和最大值的线段树,对所有的极差取(max)即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <algorithm>
    #define rin(i,a,b) for(int i=(a);i<=(b);i++)
    #define rec(i,a,b) for(int i=(a);i>=(b);i--)
    #define trav(i,a) for(int i=head[(a)];i;i=e[i].nxt)
    typedef long long LL;
    using std::cin;
    using std::cout;
    using std::endl;
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    const int MAXN=200005;
    int n,k,q,cnt,loc,ql,qr,xx[MAXN][6];
    struct sgt{
    	int maxn[33],minn[33];
    }a[MAXN<<2],kk;
    
    #define mid ((l+r)>>1)
    #define lc (o<<1)
    #define rc ((o<<1)|1)
    inline sgt mer(sgt x,sgt y){
    	rin(i,0,cnt-1) x.maxn[i]=std::max(x.maxn[i],y.maxn[i]),x.minn[i]=std::min(x.minn[i],y.minn[i]);
    	return x;
    }
    
    void build(int o,int l,int r){
    	if(l==r){
    		rin(i,0,cnt-1){
    			rin(j,0,k-1){
    				if((i>>j)&1) a[o].maxn[i]+=xx[l][j];
    				else a[o].maxn[i]-=xx[l][j];
    			}
    			a[o].minn[i]=a[o].maxn[i];
    		}
    		return;
    	}
    	build(lc,l,mid);build(rc,mid+1,r);
    	a[o]=mer(a[lc],a[rc]);
    }
    
    void upd(int o,int l,int r){
    	if(l==r){
    		a[o]=kk;
    		return;
    	}
    	if(loc<=mid) upd(lc,l,mid);
    	else upd(rc,mid+1,r);
    	a[o]=mer(a[lc],a[rc]);
    }
    
    sgt query(int o,int l,int r){
    	if(ql<=l&&r<=qr) return a[o];
    	if(mid<ql) return query(rc,mid+1,r);
    	else if(mid>=qr) return query(lc,l,mid);
    	else return mer(query(lc,l,mid),query(rc,mid+1,r));
    }
    #undef mid
    #undef lc
    #undef rc
    
    int main(){
    	n=read(),k=read();cnt=(1<<k);
    	rin(i,1,n) rin(j,0,k-1) xx[i][j]=read();
    	build(1,1,n);
    	q=read();
    	while(q--){
    		int opt=read();
    		if(opt==1){
    			loc=read();rin(i,0,k-1) xx[0][i]=read();
    			rin(i,0,cnt-1){
    				kk.maxn[i]=0;
    				rin(j,0,k-1){
    					if((i>>j)&1) kk.maxn[i]+=xx[0][j];
    					else kk.maxn[i]-=xx[0][j];
    				}
    				kk.minn[i]=kk.maxn[i];
    			}
    			upd(1,1,n);
    		}
    		else{
    			ql=read(),qr=read();
    			sgt Ans=query(1,1,n);int ans=0;
    			rin(i,0,cnt-1) ans=std::max(ans,Ans.maxn[i]-Ans.minn[i]);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    各种页的意义
    ecstore Fatal error: Class 'base_request' not found
    viewer.js 视图预览demo
    div在另一个div居中对齐
    文件权限解释rwx
    TPshop各个目录模块介绍
    tpshop linux安装下注意事项
    navicate 远程无法链接linux上mysql数据库问题
    关于破解邮箱的一点心得
    linux开启新端口
  • 原文地址:https://www.cnblogs.com/ErkkiErkko/p/10151832.html
Copyright © 2011-2022 走看看