And RMQ 区间与

https://codeforces.com/gym/103107/problem/A
const int maxn = 4e5 + 10;
int a[maxn];
int n, m;
struct seg{
    int t[maxn << 2], orr[maxn << 2];
    #define root 1, 1, n
    #define lr rt << 1
    #define rr rt << 1 | 1
    #define mid (l + r >> 1)
    #define lson lr, l, mid
    #define rson rr, mid + 1, r
    inline void pushup(int rt) {
        t[rt] = max(t[lr], t[rr]);
        orr[rt] = orr[lr] | orr[rr];
    }

    void build(int rt, int l, int r) {
        if(l == r) {
            t[rt] = orr[rt] = a[l];
            return ;
        }
        build(lson); build(rson);
        pushup(rt);
    }
    //维护区间或,显然这个值或区间所有数都是区间的数,那么如果v&区间或不变,代表v比区间或更大,不需要更新
    void ord(int rt, int l, int r, int L, int R, int v) {
        if(l == r) {
            t[rt] = orr[rt] &= v;
            return ;
        }
        if(L <= mid && (orr[lr] & v) < orr[lr])    ord(lson, L, R, v);
        if(R > mid && (orr[rr] & v) < orr[rr])     ord(rson, L, R, v);
        pushup(rt);
    }

    void update(int rt, int l, int r, int pos, int v) {
        if(l == r) {
            t[rt] = orr[rt] = v;
            return ;
        }
        if(pos <= mid)  update(lson, pos, v);
        else update(rson, pos, v);
        pushup(rt);
    }

    int query(int rt, int l, int r, int L, int R) {
        if(l >= L && r <= R) return t[rt];
        int res = 0;
        if(L <= mid)    res = query(lson, L, R);
        if(R > mid)     res = max(res, query(rson, L, R));
        return res;
    }
}T;

signed main() {
    n = rd(), m = rd();
    for(int i = 1; i <= n; ++ i)    a[i] = rd();
    T.build(root);
    for(int i = 1; i <= m; ++ i)    {
        char op[4]; scanf("%s", op);
        int l = rd(), r = rd(), v;
        if(op[0] == 'A') {
            v = rd();   T.ord(root, l, r, v);
        }
        else if(op[0] == 'U') T.update(root, l, r);
        else    printf("%d\n", T.query(root, l, r));
    }
    return 0;
}
posted @ 2021-07-11 21:26  wansheking  阅读(49)  评论(0)    收藏  举报