Codeforces 1093 G. Multidimensional Queries
阿新 • • 發佈:2018-12-28
求動態k維曼哈頓最大距離。這個很板。
線段樹這個東西和FFT,FWT之類的一樣,找位置反倒是最耗時間的,所以要把32維壓起來一起下放上傳。。。。跑的飛快
AC Code:
#include<algorithm> #include<cctype> #include<cstring> #define maxn 800005 #define inf 0x3f3f3f3f #define lc now<<1 #define rc now<<1|1 using namespace std; char cb[1<<15],*cs=cb,*ct=cb; #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++) inline void read(int &res) { char ch;bool flag=0; for(;!isdigit(ch=getc());)if(ch=='-') flag=1; for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); (flag) && (res = -res); } int n,x[maxn][5],k; int Max[maxn][32],Min[maxn][32]; void Insert(int now,int l,int r,int pos,int *a) { if(l > pos || r < pos) return; if(l==r){ for(int i=0;i<(1<<k);i++) Min[now][i]=Max[now][i]=a[i]; return;} int mid = (l+r) >> 1; Insert(lc,l,mid,pos,a),Insert(rc,mid+1,r,pos,a); for(int i=0;i<(1<<k);i++) Min[now][i]=min(Min[lc][i],Min[rc][i]), Max[now][i]=max(Max[lc][i],Max[rc][i]); } void Qmin(int now,int l,int r,int ql,int qr,int *ret) { if(l > qr || r < ql) return; if(ql <= l && r <= qr) { for(int i=0;i<(1<<k);i++) ret[i]=min(ret[i],Min[now][i]);return;} int mid = (l+r) >> 1; Qmin(lc,l,mid,ql,qr,ret),Qmin(rc,mid+1,r,ql,qr,ret); } void Qmax(int now,int l,int r,int ql,int qr,int *ret) { if(l > qr || r < ql) return; if(ql <= l && r <= qr) { for(int i=0;i<(1<<k);i++) ret[i]=max(ret[i],Max[now][i]);return;} int mid = (l+r) >> 1; Qmax(lc,l,mid,ql,qr,ret),Qmax(rc,mid+1,r,ql,qr,ret); } int calc(int sta,int loc) { int ret = 0; for(int i=0;i<k;i++) if((sta>>i) & 1) ret += x[loc][i]; else ret -= x[loc][i]; return ret; } int sta[2][32]; int main() { read(n),read(k); for(int i=1;i<=n;i++) { for(int j=0;j<k;j++) read(x[i][j]); for(int p=0;p<(1<<k);p++) sta[0][p] = calc(p,i); Insert(1,1,n,i,sta[0]); } int q; for(read(q);q--;) { int op;read(op); if(op == 1) { int i;read(i); for(int j=0;j<k;j++) read(x[i][j]); for(int p=0;p<(1<<k);p++) sta[0][p] = calc(p,i); Insert(1,1,n,i,sta[0]); } else { int l,r;read(l),read(r); int ans = 0; memset(sta[0],-0x3f,sizeof sta[0]); memset(sta[1],0x3f,sizeof sta[1]); Qmax(1,1,n,l,r,sta[0]),Qmin(1,1,n,l,r,sta[1]); for(int i=0;i<(1<<k);i++) ans = max(sta[0][i] - sta[1][i] , ans); printf("%d\n",ans); } } }