--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

洛谷__P2023 [AHOI2009] 维护序列(线段树)

题目链接:P2023 [AHOI2009] 维护序列 - 洛谷


题目大意:

有一个长为  的数列 ,有如下三种操作形式:

  1. 格式 1 t g c,表示把所有满足  的  改为  ;
  2. 格式 2 t g c 表示把所有满足  的  改为  ;
  3. 格式 3 t g 询问所有满足  的  的和,由于答案可能很大,你只需输出这个数模  的值。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#include<array>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/numeric>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
#define gmap __gnu_pbds::gp_hash_table
#define power __gnu_cxx::power
using namespace std;
typedef pair<int, int> pii;

const int N = 200086;

int n, m, mod;
int w[N];

struct node {
    int l, r;
    int add, mul, sum;
} tr[N << 4];

void pushup(int u) {
    tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % mod;
}

void pushdown(int u) {

    auto &root = tr[u], &lf = tr[u << 1], &ri = tr[u << 1 | 1];
    if (root.mul != 1) {
        lf.mul = (lf.mul * root.mul) % mod, ri.mul = (ri.mul * root.mul) % mod;
        lf.add = (lf.add * root.mul) % mod, ri.add = (ri.add * root.mul) % mod;
        lf.sum = (lf.sum * root.mul) % mod, ri.sum = (ri.sum * root.mul) % mod;
        root.mul = 1;
    }
    if (root.add) {
        lf.add = (lf.add + root.add) % mod, ri.add = (ri.add + root.add) % mod;
        lf.sum = (lf.sum + (lf.r - lf.l + 1) * root.add) % mod;
        ri.sum = (ri.sum + (ri.r - ri.l + 1) * root.add) % mod;
        root.add = 0;
    }

}

void build(int u, int l, int r) {
    tr[u] = {l, r, 0, 1, w[l] % mod};
    if (l == r) return;
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void modify1(int u, int l, int r, int x) {
    if (l <= tr[u].l && tr[u].r <= r) {
        tr[u].mul = (tr[u].mul * x) % mod;
        tr[u].add = (tr[u].add * x) % mod;
        tr[u].sum = (tr[u].sum * x) % mod;
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if (l <= mid) modify1(u << 1, l, r, x);
    if (r > mid) modify1(u << 1 | 1, l, r, x);
    pushup(u);
}


void modify2(int u, int l, int r, int x) {
    if (l <= tr[u].l && tr[u].r <= r) {
        tr[u].add = (tr[u].add + x) % mod;
        tr[u].sum = (tr[u].sum + (tr[u].r - tr[u].l + 1) * x) % mod;
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if (l <= mid) modify2(u << 1, l, r, x);
    if (r > mid) modify2(u << 1 | 1, l, r, x);
    pushup(u);
}

int query(int u, int l, int r) {
    if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum % mod;
    pushdown(u);
    
    int mid = tr[u].l + tr[u].r >> 1;
    int res = 0;
    if (l <= mid) res = query(u << 1, l, r) % mod;
    if (r > mid) res = (res + query(u << 1 | 1, l, r)) % mod;
    
    return res % mod;
}

void solve() {

    cin >> n >> mod;
    for (int i = 1; i <= n; i++) cin >> w[i];
    build(1, 1, n);
    
    cin >> m;
    while (m--) {
        int op, l, r, x;
        cin >> op >> l >> r;
        if (op == 1) {
            cin >> x;
            modify1(1, l, r, x);
        } else if (op == 2) {
            cin >> x;
            modify2(1, l, r, x);
        } else cout << query(1, l, r) % mod << endl;
        
    }
    
    
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    
    int T = 1;
// cin >> T;
    while (T--) solve();
    
    return 0;
}

 

posted @ 2025-12-27 17:44  wwjjw  阅读(11)  评论(0)    收藏  举报