线段树 相对标记+绝对标记

、#include <bits/stdc++.h>
using namespace std;

#define N 200005
#define LL long long
#define lc (u << 1)
#define rc (u << 1 | 1)
const int mod = 998244353;

int qmi(int a, int b, int p) {
    int res = 1;
    while(b) {
        if(b & 1) res = (LL)res * a % p;
        a = (LL)a * a % p;
        b >>= 1;
    }
    return res;
}

LL w[N];
struct Tree {
    int l, r;
    LL sum;
    LL lazy_set;  
    LL lazy_add;
} tr[N * 4];

void pushup(int u) {
    tr[u].sum = (tr[lc].sum + tr[rc].sum) % mod;
}

void pushdown(int u) {
    if(tr[u].lazy_set != -1) {
        // propagate set
        tr[lc].sum = (LL)(tr[lc].r - tr[lc].l + 1) * tr[u].lazy_set % mod;
        tr[rc].sum = (LL)(tr[rc].r - tr[rc].l + 1) * tr[u].lazy_set % mod;
        tr[lc].lazy_set = tr[rc].lazy_set = tr[u].lazy_set;
        tr[lc].lazy_add = tr[rc].lazy_add = 0;
        tr[u].lazy_set = -1;
    }
    if(tr[u].lazy_add) {
        tr[lc].sum = (tr[lc].sum + (LL)(tr[lc].r - tr[lc].l + 1) * tr[u].lazy_add) % mod;
        tr[rc].sum = (tr[rc].sum + (LL)(tr[rc].r - tr[rc].l + 1) * tr[u].lazy_add) % mod;
        tr[lc].lazy_add = (tr[lc].lazy_add + tr[u].lazy_add) % mod;
        tr[rc].lazy_add = (tr[rc].lazy_add + tr[u].lazy_add) % mod;
        tr[u].lazy_add = 0;
    }
}

void build(int u, int l, int r) {
    tr[u] = {l, r, w[l], -1, 0};
    if(l == r) {
        tr[u].sum = w[l] % mod;
        return;
    }
    int m = (l + r) / 2;
    build(lc, l, m);
    build(rc, m + 1, r);
    pushup(u);
}

void range_set(int u, int l, int r, LL val) {
    if(l <= tr[u].l && tr[u].r <= r) {
        tr[u].sum = (LL)(tr[u].r - tr[u].l + 1) * val % mod;
        tr[u].lazy_set = val;
        tr[u].lazy_add = 0;
        return;
    }
    pushdown(u);
    int m = (tr[u].l + tr[u].r) / 2;
    if(l <= m) range_set(lc, l, r, val);
    if(r > m)  range_set(rc, l, r, val);
    pushup(u);
}

void range_add(int u, int l, int r, LL val) {
    if(l <= tr[u].l && tr[u].r <= r) {
        tr[u].sum = (tr[u].sum + (LL)(tr[u].r - tr[u].l + 1) * val) % mod;
        tr[u].lazy_add = (tr[u].lazy_add + val) % mod;
        return;
    }
    pushdown(u);
    int m = (tr[u].l + tr[u].r) / 2;
    if(l <= m) range_add(lc, l, r, val);
    if(r > m)  range_add(rc, l, r, val);
    pushup(u);
}

LL query(int u, int l, int r) {
    if(l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
    pushdown(u);
    int m = (tr[u].l + tr[u].r) / 2;
    LL res = 0;
    if(l <= m) res = (res + query(lc, l, r)) % mod;
    if(r > m)  res = (res + query(rc, l, r)) % mod;
    return res;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) cin >> w[i];
    build(1, 1, n);

    while(m--) {
        int l, r;
        cin >> l >> r;
        LL total = query(1, l, r);
        int len = r - l + 1;
        LL each = total * qmi(len, mod - 2, mod) % mod;
        range_set(1, l, r, 0);
        range_add(1, l, r, each);
    }

    for(int i = 1; i <= n; ++i)
        cout << query(1, i, i) << " \n"[i == n];

    return 0;
}

posted on 2025-08-04 17:21  下头小美  阅读(9)  评论(0)    收藏  举报