bzoj 5312 冒险

给出了一个自然数序列a,每次有一下三种操作。
1,给出l,r,x,将序列l,r之间的所有数都 and x
2,给出l,r,x,将序列l,r之间的所有数都 or x
3,给出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 }
bzoj 5312 冒险
posted @ 2018-08-17 17:10  KingSann  阅读(129)  评论(0编辑  收藏  举报