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 ;
}

浙公网安备 33010602011771号