P3373 【模板】线段树 2

考虑到有乘法和加法,因此要考虑一个优先的,考虑乘法优先,子节点的懒标记mul更新为mulm而add为addm+a。

点击查看代码
#include <iostream>
#include <stack>
#include <cmath>
#include <algorithm>
#include <set>
#include <vector>
#include <climits>
#include <string.h>
#include <map>
#include <queue>
#include <list>
#include <cmath>
#include <iomanip> 
#define int long long 
#define ios ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lc u<<1
#define rc u<<1|1
#define gcd __gcd
#define double long double
#define endl "\n"
#define INF LLONG_MAX
#define mod  1000000007
#define N 100005
const double PI = 3.14159265358979323846;
using namespace std;
struct Node {int l, r, sum, mul, add;}tr[N*4];
int n, p, q,a[N];
void pushup(int u) { tr[u].sum = (tr[lc].sum + tr[rc].sum)%p; }
void calc(Node &t, int m, int a)//先乘后加
{
    t.sum = (t.sum * m + (t.r - t.l + 1) * a) % p;
    t.mul = t.mul * m % p;
    t.add = (t.add * m + a) % p;
}
void pushdown(int u)//懒标记下传
{
    calc(tr[lc], tr[u].mul, tr[u].add);
    calc(tr[rc], tr[u].mul, tr[u].add);
    tr[u].add = 0; tr[u].mul = 1;
}
void build(int u, int l, int r)
{
    tr[u] = { l,r,a[l],1,0 };
    if (l == r)return;
    int mid = l + r >> 1;
    build(lc, l, mid); build(rc, mid + 1, r);
    pushup(u);
}
void change(int u, int l, int r, int m, int a)
{
    if (l > tr[u].r || r < tr[u].l)return;
    if (l <= tr[u].l && tr[u].r <= r)
    {
        calc(tr[u], m, a);//加了懒标记
        return;
    }
    pushdown(u);
    change(lc, l, r, m, a); change(rc, l, r, m, a);
    pushup(u);
}
int query(int u, int l, int r)
{
    if (l > tr[u].r || r < tr[u].l) return 0;
    if (l <= tr[u].l && r >= tr[u].r)return tr[u].sum;
    pushdown(u);
    return (query(lc, l, r) + query(rc, l , r)) % p;//查询
}
signed main()
{
    ios;//会超时
    cin >> n >> q >> p;
    for (int i = 1; i <= n; i++)cin >> a[i];
    build(1, 1, n);
    while (q--)
    {
        int op; cin >> op;
        if (op == 1)
        {
            int x, y, k; cin >> x >> y >> k;
            change(1, x, y, k,0);
        }
        else if (op == 2)
        {
            int x, y, k; cin >> x >> y >> k;
            change(1, x, y, 1,k);
        }
        else
        {
            int x, y; cin >> x >> y;
            cout << query(1, x, y) << endl;
        }
    }

}
posted @ 2024-10-12 16:34  Aloongyy  阅读(12)  评论(0)    收藏  举报