CF1093GMultidimensional Queries题解
CF1093GMultidimensional Queries题解
于此题一样,只不过多了单点修改和区间查询,
怎么维护,套个线段树即可。
#include<bits/stdc++.h>
#define ll long long
#define lc x<<1
#define rc x<<1|1
#define re register
#define reg Register
using namespace std;
const int N=2e5+6;
struct xd{
int z[33],maxs;
void clr(){memset(z,0,sizeof(z)); maxs=0;}
}p[N],w[N<<2],tmp;
int n,q,k,P,opt,t1,t2,t[7];
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
inline xd pushup(xd u,xd v){
xd o; o.clr(); o.maxs=max(u.maxs,v.maxs);
for(int i=0;i<P;++i) o.maxs=max(u.z[i]+v.z[P-1-i],o.maxs),o.z[i]=max(u.z[i],v.z[i]);
return o;
}
void build(int l,int r,int x){
if(l==r){w[x]=p[l],w[x].maxs=0; return;}
int mid=l+r>>1;
build(l,mid,lc),build(mid+1,r,rc);
w[x]=pushup(w[lc],w[rc]);
}
void update(int l,int r,int u,int x){
if(l==r){w[x]=tmp; return;}
int mid=l+r>>1;
if(u<=mid) update(l,mid,u,lc);
else update(mid+1,r,u,rc);
w[x]=pushup(w[lc],w[rc]);
}
xd query(int l,int r,int u,int v,int x){
if(u<=l&&r<=v) return w[x];
int mid=l+r>>1;
if(v<=mid) return query(l,mid,u,v,lc);
if(u>mid) return query(mid+1,r,u,v,rc);
return pushup(query(l,mid,u,v,lc),query(mid+1,r,u,v,rc));
}
int main(){
n=read(),k=read(),P=(1<<k);
for(re int i=1;i<=n;++i){
for(re int j=0;j<k;++j) t[j]=read();
for(re int j=0;j<P;++j){
for(re int o=0;o<k;++o){
if(j&(1<<o)) p[i].z[j]+=t[o];
else p[i].z[j]-=t[o];
}
}
}
build(1,n,1);
q=read();
for(re int i=1;i<=q;++i){
opt=read(),t1=read();
if(opt==1){
tmp.clr();
for(re int j=0;j<k;++j) t[j]=read();
for(re int j=0;j<P;++j)
for(re int o=0;o<k;++o){
if(j&(1<<o)) tmp.z[j]+=t[o];
else tmp.z[j]-=t[o];
}
update(1,n,t1,1);
}
else t2=read(),printf("%d\n",query(1,n,t1,t2,1).maxs);
}
return 0;
}