bzoj 5312 冒险
给出了一个自然数序列a,每次有一下三种操作。1,给出l,r,x,将序列l,r之间的所有数都 and x2,给出l,r,x,将序列l,r之间的所有数都 or x3,给出l,r,询问l,r之间的最大值
迷之复杂度分析……不会……
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = (2e5 + 10) * 10; 4 5 int n, m; 6 7 int tag[N], mx[N], sumand[N], sumor[N]; 8 9 #define lc (id << 1) 10 #define rc (id << 1 | 1) 11 12 void push(int id) { 13 if(tag[id] != -1) { 14 mx[id] = sumand[id] = sumor[id] = tag[id]; 15 tag[lc] = tag[rc] = tag[id]; 16 tag[id] = -1; 17 } 18 } 19 20 void update(int id) { 21 push(id), push(lc), push(rc); 22 mx[id] = max(mx[lc], mx[rc]); 23 sumand[id] = sumand[lc] & sumand[rc]; 24 sumor[id] = sumor[lc] | sumor[rc]; 25 } 26 27 void build(int id, int l, int r) { 28 int mid = (l + r) >> 1; 29 tag[id] = -1; 30 if(l == r) { 31 scanf("%d", &mx[id]); 32 sumand[id] = sumor[id] = mx[id]; 33 } else { 34 build(lc, l, mid), build(rc, mid + 1, r); 35 mx[id] = max(mx[lc], mx[rc]); 36 sumand[id] = sumand[lc] & sumand[rc]; 37 sumor[id] = sumor[lc] | sumor[rc]; 38 } 39 } 40 41 void modify(int id, int l, int r, int ql, int qr, int x, int type) { 42 push(id); 43 int mid = (l + r) >> 1; 44 if(l == r || 45 (ql <= l && r <= qr 46 47 && 48 ( (type == 0 && (sumand[id] & x) == (sumor[id] & x)) 49 || (type == 1 && (sumand[id] | x) == (sumor[id] | x))) 50 )) { 51 52 if(type == 0) tag[id] = x & mx[id]; 53 else tag[id] = x | mx[id]; 54 // printf("[%d, %d]: %d\n", l, r, tag[id]); 55 } else if(qr <= mid) modify(lc, l, mid, ql, qr, x, type), update(id); 56 else if(ql >= mid + 1) modify(rc, mid + 1, r, ql, qr, x, type), update(id); 57 else modify(lc, l, mid, ql, mid, x, type), modify(rc, mid + 1, r, mid + 1, qr, x, type), update(id); 58 } 59 60 int query(int id, int l, int r, int ql, int qr) { 61 push(id); 62 int mid = (l + r) >> 1; 63 if(ql <= l && r <= qr) return mx[id]; 64 else if(qr <= mid) return query(lc, l, mid, ql, qr); 65 else if(ql >= mid + 1) return query(rc, mid + 1, r, ql, qr); 66 else return max(query(lc, l, mid, ql, mid), query(rc, mid + 1, r, mid + 1, qr)); 67 } 68 69 int main() { 70 scanf("%d%d", &n, &m); 71 build(1, 1, n); 72 for(int i = 1, op, l, r, x ; i <= m ; ++ i) { 73 scanf("%d%d%d", &op, &l, &r); if(op != 3) scanf("%d", &x); 74 if(op == 1) { 75 modify(1, 1, n, l, r, x, 0); 76 } else if(op == 2) { 77 modify(1, 1, n, l, r, x, 1); 78 } else { 79 printf("%d\n", query(1, 1, n, l, r)); 80 } 81 82 // for(int j = 1 ; j <= n ; ++ j) printf("%d ", query(1, 1, n, j, j)); 83 // cout << endl; 84 85 } 86 }