Multidimensional Queries(二进制枚举+线段树+Educational Codeforces Round 56 (Rated for Div. 2))

题目链接:

  https://codeforces.com/contest/1093/problem/G

题目:

题意:

  在k维空间中有n个点,每次给你两种操作,一种是将某一个点的坐标改为另一个坐标,一种操作是查询[l,r]中曼哈顿距离最大的两个点的最大曼哈顿距离。

思路:

  对于曼哈顿距离,我们将其绝对值去掉会发现如下规律(以二维为例):

    

  故这题我们可以用线段树来维护[l,r]中上述每种情况的最大值和最小值,用二进制来枚举xy的符号(1为正,0为负),最后答案是 每种情况中区间最大值-区间最小值 的最大值。

代码实现如下:

  1 #include <set>
  2 #include <map>
  3 #include <deque>
  4 #include <queue>
  5 #include <stack>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <bitset>
  9 #include <cstdio>
 10 #include <string>
 11 #include <vector>
 12 #include <cstdlib>
 13 #include <cstring>
 14 #include <iostream>
 15 #include <algorithm>
 16 using namespace std;
 17
 18 typedef long long LL;
 19 typedef pair<LL, LL> pLL;
 20 typedef pair<LL, int> pli;
 21 typedef pair<int, LL> pil;;
 22 typedef pair<int, int> pii;
 23 typedef unsigned long long uLL;
 24
 25 #define lson rt<<1
 26 #define rson rt<<1|1
 27 #define lowbit(x) x&(-x)
 28 #define  name2str(name) (#name)
 29 #define bug printf("*********\n")
 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
 31 #define FIN freopen("D://code//in.txt", "r", stdin)
 32 #define IO ios::sync_with_stdio(false),cin.tie(0)
 33
 34 const double eps = 1e-8;
 35 const int mod = 1000000007;
 36 const int maxn = 2e5 + 7;
 37 const double pi = acos(-1);
 38 const int inf = 0x3f3f3f3f;
 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 40
 41 int n, k, q, op, x, l, r;
 42 int a[maxn][10], num[10];
 43
 44 struct node {
 45     int l, r, mx, mn;
 46 }segtree[maxn<<2][33];
 47
 48 void push_up(int rt, int pp) {
 49     segtree[rt][pp].mx = max(segtree[lson][pp].mx, segtree[rson][pp].mx);
 50     segtree[rt][pp].mn = min(segtree[lson][pp].mn, segtree[rson][pp].mn);
 51 }
 52
 53 void build(int rt, int l, int r, int pp) {
 54     segtree[rt][pp].l = l, segtree[rt][pp].r = r;
 55     segtree[rt][pp].mx = segtree[rt][pp].mn = 0;
 56     if(l == r) {
 57         for(int i = 0; i < k; i++) {
 58             if(pp & (1<<i)) {
 59                 segtree[rt][pp].mx += a[l][i];
 60                 segtree[rt][pp].mn += a[l][i];
 61             } else {
 62                 segtree[rt][pp].mx -= a[l][i];
 63                 segtree[rt][pp].mn -= a[l][i];
 64             }
 65         }
 66         return;
 67     }
 68     int mid = (l + r) >> 1;
 69     build(lson, l, mid, pp);
 70     build(rson, mid + 1, r, pp);
 71     push_up(rt, pp);
 72 }
 73
 74 void update(int rt, int pos, int pp) {
 75     if(segtree[rt][pp].l == segtree[rt][pp].r) {
 76         segtree[rt][pp].mx = segtree[rt][pp].mn = 0;
 77         for(int i = 0; i < k; i++) {
 78             if(pp & (1<<i)) {
 79                 segtree[rt][pp].mx += num[i];
 80                 segtree[rt][pp].mn += num[i];
 81             } else {
 82                 segtree[rt][pp].mx -= num[i];
 83                 segtree[rt][pp].mn -= num[i];
 84             }
 85         }
 86         return;
 87     }
 88     int mid = (segtree[rt][pp].l + segtree[rt][pp].r) >> 1;
 89     if(pos <= mid) update(lson, pos, pp);
 90     else update(rson, pos, pp);
 91     push_up(rt, pp);
 92 }
 93
 94 int query(int rt, int l, int r, int pp, int op) {
 95     if(segtree[rt][pp].l >= l && segtree[rt][pp].r <= r) {
 96         if(op == 1) {
 97             return segtree[rt][pp].mx;
 98         } else {
 99             return segtree[rt][pp].mn;
100         }
101     }
102     int mid = (segtree[rt][pp].l + segtree[rt][pp].r) >> 1;
103     if(r <= mid) return query(lson, l, r, pp, op);
104     else if(l > mid) return query(rson, l, r, pp, op);
105     else {
106         if(op == 1) return max(query(lson, l, mid, pp, op), query(rson, mid + 1, r, pp, op));
107         else return min(query(lson, l, mid, pp, op), query(rson, mid + 1, r, pp, op));
108     }
109 }
110
111 int main(){
112 #ifndef ONLINE_JUDGE
113     FIN;
114 #endif
115     scanf("%d%d", &n, &k);
116     for(int i = 1; i <= n; i++) {
117         for(int j = 0; j < k; j++) {
118             scanf("%d", &a[i][j]);
119         }
120     }
121     for(int i = 0; i < (1<<k); i++) {
122         build(1, 1, n, i);
123     }
124     scanf("%d", &q);
125     while(q--) {
126         scanf("%d", &op);
127         if(op == 1) {
128             scanf("%d", &x);
129             for(int i = 0; i < k; i++) {
130                 scanf("%d", &num[i]);
131             }
132             for(int i = 0; i <(1<<k); i++) {
133                 update(1, x, i);
134             }
135         } else {
136             scanf("%d%d", &l, &r);
137             int mx = -inf;
138             for(int i = 0; i < (1<<k); i++) {
139                 mx = max(mx, query(1, l, r, i, 1) - query(1, l, r, i, 2));
140             }
141             printf("%d\n", mx);
142         }
143     }
144     return 0;
145 }

原文地址:https://www.cnblogs.com/Dillonh/p/10125587.html

时间: 2024-08-15 06:44:51

Multidimensional Queries(二进制枚举+线段树+Educational Codeforces Round 56 (Rated for Div. 2))的相关文章

Educational Codeforces Round 56 (Rated for Div. 2)

涨rating啦.. 不过话说为什么有这么多数据结构题啊,难道是中国人出的? A - Dice Rolling 傻逼题,可以用一个三加一堆二或者用一堆二,那就直接.. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<c

Educational Codeforces Round 56 (Rated for Div. 2) ABCD

题目链接:https://codeforces.com/contest/1093 A. Dice Rolling 题意: 有一个号数为2-7的骰子,现在有一个人他想扔到几就能扔到几,现在问需要扔多少次,能使扔出的总和等于xi. 题解: 由于是special judge,模拟一下搞搞就行了= = 代码如下: #include <bits/stdc++.h> using namespace std; int main(){ int t; cin>>t; int n; while(t--

Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\(in_i,out_i\),并满足\(out_i>in_i\).定义套娃\(i\)能套在套娃\(j\)里面,当且仅当\(out_i\leq in_j\). 定义极大套娃组:当且仅当不能有另外一个套娃套在它们身上. 定义套娃组额外空间为\(in_1+(in_2-out_1)+\cdots +(in_k-

Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest

Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest(dp+线段树) 题目链接 题意: 给定3个人互不相同的多个数字,可以把数字移动给别人,问最少移动几次后可以使第一个人的数字为1~m1,第二个人m1~m2,第三个人m2~n(可以没有数字) 题解: 设c[1][i]为第一个人m1为i时需要移动的次数,c[3][i]为m2为i是第三个人需要操作的次数,当其他两个人数字合法时,第二个人的数字也会合法.枚举第一个人的每个i,

Educational Codeforces Round 36 (Rated for Div. 2) 题解

Educational Codeforces Round 36 (Rated for Div. 2) 题目的质量很不错(不看题解做不出来,笑 Codeforces 920C 题意 给定一个\(1\)到\(n\)组成的数组,只可以交换某些相邻的位置,问是否可以将数组调整为升序的 解题思路 首先如果每个数都能通过交换到它应该到的位置,那么就可以调整为升序的. 但实际上交换是对称的,如果应该在的位置在当前位置前方的数都交换完成,那么整体就是排好序的,因为不可能所有不在相应位置的数都在相应位置的后方.

Educational Codeforces Round 59 (Rated for Div. 2) DE题解

Educational Codeforces Round 59 (Rated for Div. 2) D. Compression 题目链接:https://codeforces.com/contest/1107/problem/D 题意: 给出一个n*(n/4)的矩阵,这个矩阵原本是一些01矩阵,但是现在四个四个储存进二进制里面,现在给出的矩阵为0~9以及A~F,表示0~15. 然后问这个矩阵能否压缩为一个(n/x)*(n/x)的矩阵,满足原矩阵中大小为x*x的子矩阵所有数都相等(所有子矩阵构

Educational Codeforces Round 80 (Rated for Div. 2)

\[Educational\ Codeforces\ Round\ 80\ (Rated\ for\ Div.\ 2)\] A.Deadline 打勾函数找最小值,在\(\sqrt{d}\)邻域里找\(x\)最小化\(x+\lceil\frac{d}{x+1}\rceil\)即可 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://codeforces.com/contest/985/problem/E Description Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome w

Educational Codeforces Round 55 (Rated for Div. 2)

Educational Codeforces Round 55 (Rated for Div. 2) 链接 A Vasya and Book 傻逼题..注意判边界. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<cm