1. 程式人生 > >CF 1093 G. Multidimensional Queries

CF 1093 G. Multidimensional Queries

G. Multidimensional Queries

連結

分析:

  考慮如何去掉絕對值符號。

  $\sum \limits_{i = 1}^{k} |a_{x, i} - a_{y, i}|$,由於k比較小,考慮列舉每一維的符號,發現如果不是最終的答案,結果會變小,不影響取max的操作。

  然後就是單點修改,區間查詢最大最小值。

程式碼:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5
#include<cmath> 6 #include<cctype> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 #include<map> 11 #define Root 1, n, 1 12 #define lson l, mid, rt << 1 13 #define rson mid + 1, r, rt << 1 | 1 14 using namespace std; 15 typedef long
long LL; 16 17 inline int read() { 18 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 19 for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 20 } 21 22 const int N = 200005; 23 struct Node{ int x[6]; }A[N]; 24 struct Que{ int opt, x[6], l, r; }Q[N]; 25 int
ans[N]; 26 27 struct SegmentTree{ 28 int mx[N << 2], mn[N << 2]; 29 void update(int l,int r,int rt,int p,int x) { 30 if (l == r) { mn[rt] = mx[rt] = x; return; } 31 int mid = (l + r) >> 1; 32 if (p <= mid) update(lson, p, x); 33 else update(rson, p, x); 34 mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]); 35 mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]); 36 } 37 int query_min(int l,int r,int rt,int L,int R) { 38 if (L <= l && r <= R) return mn[rt]; 39 int mid = (l + r) >> 1; 40 if (R <= mid) return query_min(lson, L, R); 41 else if (L > mid) return query_min(rson, L, R); 42 else return min(query_min(lson, L, R), query_min(rson, L, R)); 43 } 44 int query_max(int l,int r,int rt,int L,int R) { 45 if (L <= l && r <= R) return mx[rt]; 46 int mid = (l + r) >> 1; 47 if (R <= mid) return query_max(lson, L, R); 48 else if (L > mid) return query_max(rson, L, R); 49 else return max(query_max(lson, L, R), query_max(rson, L, R)); 50 } 51 }T; 52 53 int main() { 54 int n = read(), k = read(); 55 for (int i = 1; i <= n; ++i) 56 for (int j = 0; j < k; ++j) A[i].x[j] = read(); 57 int m = read(); 58 for (int i = 1; i <= m; ++i) { 59 Q[i].opt = read(); Q[i].r = -1; 60 if (Q[i].opt == 1) { 61 Q[i].l = read(); 62 for (int j = 0; j < k; ++j) Q[i].x[j] = read(); 63 } 64 else { 65 Q[i].l = read(), Q[i].r = read(); 66 } 67 } 68 int S = (1 << k) - 1, now; 69 for (int s = 0; s <= S; ++s) { 70 for (int i = 1; i <= n; ++i) { 71 now = 0; 72 for (int j = 0; j < k; ++j) now += ((s >> j) & 1) ? (A[i].x[j]) : (-A[i].x[j]); 73 T.update(Root, i, now); 74 } 75 for (int i = 1; i <= m; ++i) { 76 if (Q[i].opt == 2) { 77 int mn = T.query_min(Root, Q[i].l, Q[i].r); 78 int mx = T.query_max(Root, Q[i].l, Q[i].r); 79 ans[i] = max(ans[i], mx - mn); 80 } 81 else { 82 now = 0; 83 for (int j = 0; j < k; ++j) now += ((s >> j) & 1) ? (Q[i].x[j]) : (-Q[i].x[j]); 84 T.update(Root, Q[i].l, now); 85 } 86 } 87 } 88 for (int i = 1; i <= m; ++i) { 89 if (Q[i].r == -1) continue; 90 printf("%d\n", ans[i]); 91 } 92 return 0; 93 }