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

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

洛谷__P1438 无聊的数列(线段树)

题目链接:P1438 无聊的数列 - 洛谷


题目大意:

维护一个数列 ,支持两种操作:

  • 1 l r K D:给出一个长度等于  的等差数列,首项为 ,公差为 ,并将它对应加到  范围中的每一个数上。 即:令 。

  • 2 p:询问序列的第  个数的值 


思路:

维护每段区间的首项,公差即可


代码:

#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>
#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))
using namespace std;
typedef pair<int, int> pii;

const int N = 200086, mod = 998244353;

int n, m;
int w[N];

struct node {
    int l, r;
    int s, a, d;//区间和,首项,公差
} e[N << 2];

void pushup(int u) {
    e[u].s = e[u << 1].s + e[u << 1 | 1].s;
}

void pushdown(int u) {

    auto &root = e[u], &lf = e[u << 1], &ri = e[u << 1 | 1];
    lf.a += root.a, lf.d += root.d;
    ri.a += root.a + (ri.l - lf.l) * root.d;
    ri.d += root.d;
    root.a = root.d = 0;   
}

void build(int u, int l, int r) {

    if (l == r) e[u] = {l, r, w[l], 0, 0};
    else {
        e[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

void modify(int u, int l, int r, int a, int d) {

    if (l <= e[u].l && e[u].r <= r) {  
        e[u].a += (e[u].l - l) * d + a;
        e[u].d += d;
    } else {
        pushdown(u);
        int mid = e[u].r + e[u].l >> 1;
        if (l <= mid) modify(u << 1, l, r, a, d);
        if (r > mid) modify(u << 1 | 1, l, r, a, d);
        pushup(u);
    }
}

int query(int u, int x) {

    if (e[u].l == x && e[u].r == x) {
        e[u].s += e[u].a;
        e[u].a = e[u].d = 0;
        return e[u].s;
    }
    
    pushdown(u);
    int mid = e[u].l + e[u].r >> 1;
    if (x <= mid) return query(u << 1, x);
    else return query(u << 1 | 1, x); 
}

void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> w[i];
    
    build(1, 1, n);
    while (m--) {
        int op, l, r, a, d;
        cin >> op >> l;
        if (op == 1) {
            cin >> r >> a >> d;
            modify(1, l, r, a, d);
        } else cout << query(1, l) << 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-10-30 15:50  wwjjw  阅读(26)  评论(0)    收藏  举报