1 条题解

  • 0
    @ 2022-3-3 15:55:30

    很有趣的题。

    考虑绝对值的本质是 aba-bbab-a 的较大值。

    由于 kk 只有 55,直接装压每一维乘上一还是负一,然后就做完了。


    代码
    #include<bits/stdc++.h>
    #define mid (l+r>>1)
    #define seg int p,int l,int r
    #define lid p<<1,l,mid
    #define rid p<<1|1,mid+1,r
    using namespace std;
    const int N=2e5+5;
    struct segtree{int a[35];}tr[N<<2];
    int n,k,_,a[N][10];
    segtree operator +(segtree a,segtree b){
    	segtree ans;
    	for(int i=0;i<1<<k;i++)ans.a[i]=max(a.a[i],b.a[i]);
    	return ans;
    }
    void add(seg,int x){
    	if(l==r){
    		for(int i=0;i<1<<k;i++){
    			tr[p].a[i]=0;
    			for(int j=0;j<k;j++){
    				if(i&(1<<j))tr[p].a[i]+=a[l][j+1];
    				else tr[p].a[i]-=a[l][j+1];
    			}
    		}
    		return;
    	}
    	if(x<=mid)add(lid,x);
    	else add(rid,x);
    	tr[p]=tr[p<<1]+tr[p<<1|1];
    }
    segtree ask(seg,int L,int R){
    	if(l>=L&&r<=R)return tr[p];
    	segtree ans;
    	for(int i=0;i<1<<k;i++)ans.a[i]=-1e9;
    	if(L<=mid)ans=ans+ask(lid,L,R);
    	if(R>mid)ans=ans+ask(rid,L,R);
    	return ans;
    }
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=k;j++)scanf("%d",&a[i][j]);
    		add(1,1,n,i);
    	}
    	scanf("%d",&_);
    	while(_--){
    		int T,x,l,r;
    		scanf("%d",&T);
    		if(T==1){
    			scanf("%d",&x);
    			for(int i=1;i<=k;i++)scanf("%d",&a[x][i]);
    			add(1,1,n,x);
    		}
    		else{
    			scanf("%d%d",&l,&r);
    			auto t=ask(1,1,n,l,r);
    			int ans=0;
    			for(int i=0;i<1<<k;i++)ans=max(ans,t.a[i]+t.a[(1<<k)-i-1]);
    			printf("%d\n",ans);
    		}
    	}
    }
    
    • 1

    信息

    ID
    87
    时间
    6000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者