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 }

 

posted @ 2018-12-29 17:56  MJT12044  阅读(197)  评论(0编辑  收藏  举报