2021杭电多校第八场

这个第二个操作是比较常见的区间nlogn^2的操作,比如区间与,区间根号,区间取模,区间lowbit
第三个操作是维护区间最高位的和,乘二

int a[maxn];
struct seg{
    const int mod = 998244353;
    int t[maxn << 2], lz[maxn << 2];
    int h[maxn << 2];
    bool tag[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

    int qmod(int x) {
        if(x >= mod)    x -= mod;
        return x;
    }

    int lowbit(int x) {
        return x & -x;
    }

    void push(int rt) {
        t[rt] = qmod(t[lr] + t[rr]);
        h[rt] = qmod(h[lr] + h[rr]);
        tag[rt] = tag[lr] & tag[rr];
    }

    void down(int rt, int l, int r) {
        if(lz[rt] == 1) return ;
        h[lr] = 1ll * h[lr] * lz[rt] % mod;
        h[rr] = 1ll * h[rr] * lz[rt] % mod;
        lz[lr] = 1ll * lz[lr] * lz[rt] % mod;
        lz[rr] = 1ll * lz[rr] * lz[rt] % mod;

        lz[rt] = 1;
    }

    void build(int rt, int l, int r) {
        tag[rt] = 0;    lz[rt] = 1;
        if(l == r) {
            int x = a[l];
            while(x != lowbit(x)) x -= lowbit(x);
            h[rt] = x;  t[rt] = a[l] - x;
            return ;
        }
        build(lson);    build(rson);
        push(rt);
    }

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

    void add(int rt, int l, int r, int L, int R) {
        if(tag[rt]) return ;
        if(l >= L && r <= R) {
            lz[rt] = qmod(lz[rt] + lz[rt]);
            h[rt] = qmod(h[rt] + h[rt]);
            return ;
        }
        down(rt, l, r);
        if(L <= mid)    add(lson, L, R);
        if(R >  mid)    add(rson, L, R);
        push(rt);
    }

    void del(int rt, int l, int r, int L, int R) {
        if(tag[rt]) return ;
        if(l == r) {
            if(t[rt] == 0) {
                h[rt] = 0;
                tag[rt] = 1;
            }
            t[rt] -= lowbit(t[rt]);
            return ;
        }
        down(rt, l, r);
        if(L <= mid)    del(lson, L, R);
        if(R >  mid)    del(rson, L, R);
        push(rt);
    }
}T;

void run() {
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
    T.build(root);
    int m; scanf("%d", &m);
    for(int i = 1; i <= m; ++ i) {
        int op, l, r;   scanf("%d %d %d", &op, &l, &r);
        if(op == 1) printf("%d\n", T.query(root, l, r));
        else if(op == 2)    T.del(root, l, r);
        else                T.add(root, l, r);
    }
    return ;
}
posted @ 2021-08-13 09:24  wlhp  阅读(18)  评论(0)    收藏  举报