Codeforces 1093G題解(線段樹維護k維空間最大曼哈頓距離)
阿新 • • 發佈:2018-12-16
題意是,給出n個k維空間下的點,然後q次操作,每次操作要麼修改其中一個點的座標,要麼查詢下標為[l,r]區間中所有點中兩點的最大曼哈頓距離。
思路:參考blog:https://blog.csdn.net/Anxdada/article/details/81980574,裡面講了k維空間中的最大曼哈頓距離求法,然後利用這個方案改一改,用線段樹來維護這些值就好了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #defineView Codemem(x) memset(x,0,sizeof x) 5 #define lson o*2 6 #define rson o*2+1 7 #define m (l+r)/2 8 const int maxn=200005; 9 struct node 10 { 11 int mi,mx; 12 }tr[4*maxn][35]; 13 void pushup(int o,int idx) 14 { 15 tr[o][idx].mi=min(tr[lson][idx].mi,tr[rson][idx].mi); 16 tr[o][idx].mx=max(tr[lson][idx].mx,tr[rson][idx].mx);17 } 18 int tmp[maxn][35]; 19 int a[maxn][35]; 20 void build(int o,int l,int r,int idx); 21 void update(int o,int l,int r,int x,int idx); 22 int cal(int n,int k) 23 { 24 int ans = 0, mi, mx, t; 25 for (int s = 0 ; s < (1<<k) ; s ++) 26 { 27 mi = 1e9, mx = -1e9;28 for (int i = 1 ; i <= n ; i++) 29 { 30 t = a[i][0]; 31 for (int j = 1 ; j < k ; j++) 32 { 33 if ((1<<j) & s) t += a[i][j]; 34 else t -= a[i][j]; 35 } 36 mi = min(mi, t); 37 mx = max(mx, t); 38 tmp[i][s]=t; 39 } 40 build(1,1,n,s); 41 ans = max(ans, mx-mi); 42 } 43 return ans; 44 } 45 int cal2(int x,int n,int k) 46 { 47 int t; 48 for (int s = 0 ; s < (1<<k) ; s ++) 49 { 50 int i=x; 51 t = a[i][0]; 52 for (int j = 1 ; j < k ; j++) 53 { 54 if ((1<<j) & s) t += a[i][j]; 55 else t -= a[i][j]; 56 } 57 tmp[i][s]=t; 58 update(1,1,n,i,s); 59 } 60 } 61 void build(int o,int l,int r,int idx) 62 { 63 if(l==r) 64 { 65 tr[o][idx].mi=tr[o][idx].mx=tmp[l][idx]; 66 return; 67 } 68 build(lson,l,m,idx); 69 build(rson,m+1,r,idx); 70 pushup(o,idx); 71 } 72 void update(int o,int l,int r,int x,int idx) 73 { 74 if(l==r) 75 { 76 tr[o][idx].mi=tr[o][idx].mx=tmp[l][idx]; 77 return; 78 } 79 if(x<=m) update(lson,l,m,x,idx); 80 else update(rson,m+1,r,x,idx); 81 pushup(o,idx); 82 } 83 int query(int o,int l,int r,int ql,int qr,int mark,int idx) 84 { 85 if(ql<=l&&qr>=r) 86 { 87 if(mark==1) 88 return tr[o][idx].mi; 89 else 90 return tr[o][idx].mx; 91 } 92 if(qr<=m) 93 return query(lson,l,m,ql,qr,mark,idx); 94 if(ql>m) 95 return query(rson,m+1,r,ql,qr,mark,idx); 96 if(mark==1) 97 return min(query(lson,l,m,ql,qr,mark,idx),query(rson,m+1,r,ql,qr,mark,idx)); 98 else 99 return max(query(lson,l,m,ql,qr,mark,idx),query(rson,m+1,r,ql,qr,mark,idx)); 100 } 101 int main() 102 { 103 int n,k; 104 scanf("%d%d",&n,&k); 105 for(int i=1;i<=n;i++) 106 for(int j=0;j<k;j++) 107 scanf("%d",&a[i][j]); 108 cal(n,k); 109 int q; 110 scanf("%d",&q); 111 while(q--) 112 { 113 int op; 114 scanf("%d",&op); 115 if(op==1) 116 { 117 int x; 118 scanf("%d",&x); 119 for(int i=0;i<k;i++) 120 scanf("%d",&a[x][i]); 121 cal2(x,n,k); 122 } 123 else 124 { 125 int l,r; 126 scanf("%d%d",&l,&r); 127 int ans=0; 128 for (int s = 0 ; s < (1<<k) ; s ++) 129 { 130 int mi=1e9; 131 int mx=-1e9; 132 mi=min(mi,query(1,1,n,l,r,1,s)); 133 mx=max(mx,query(1,1,n,l,r,2,s)); 134 ans=max(ans,mx-mi); 135 } 136 printf("%d\n",ans); 137 } 138 } 139 }