线段树无查封0pts求条悬官
查看原帖
线段树无查封0pts求条悬官
741580
niuqichongtian楼主2024/11/13 18:31

线段树
无差分
0分
求调 悬关

将用此账号 关注

#include <bits/stdc++.h>
#define I using
#define AK namespace
#define IOI std
#undef int
#define int long long
#undef INT_MIN
#define INT_MIN (LONG_LONG_MIN + 1145)
#undef INT_MAX
#define INT_MAX (LONG_LONG_MAX - 1145)
#define P1 "标记点1"
#define P2 "标记点2"
#define P3 "标记点3"
#define P4 "标记点4"
#define P5 "标记点5"
#define P6 "标记点6"
#define P7 "标记点7"
#define P8 "标记点8"
#define P9 "标记点9"
#define P0 "标记点0"
I AK IOI;

namespace CSP {
    inline void read(int &x) {
        x = 0;
        char c = getchar();
        int pn = 1;
        while (!isdigit(c)) {
            if (c == '-') pn = -1;
            c = getchar();
        }
        while (isdigit(c)) {
            x = x * 10 + c - 48;
            c = getchar();
        }
        x *= pn;
        return;
    }
    inline void write(int x) {
        if (x < 0)
            putchar('-'), x = -x;
        if (x >= 10)
            write(x / 10);
        putchar(x % 10 + 48);
        return;
    }
    struct inputstream {
        inputstream operator>>(int &x) {
            read(x);
            return *this;
        }
    } in;
    struct outputstream {
        outputstream operator<<(int x) {
            write(x);
            putchar(10);
            return *this;
        }
    } out;
}
I AK CSP;//快读快写

int N, Q;
int t[400007];
int p[400007];
struct tag {
    int strt;
    int diff;
    tag(int x = 0, int y = 0) {
        strt = x;
        diff = y;
    }
    void operator+=(tag x) {
        this->strt += x.strt;
        this->diff += x.diff;
        return;
    }
};
tag lzy[400007];

AK NOI {
    inline bool in_range(int L, int R, int l, int r) {
        if (l <= L && R <= r)
            return true;
        return false;
    }
    inline bool out_range(int L, int R, int l, int r) {
        if (R < l || r < L)
            return true;
        return false;
    }
    inline void maketag(int u, int L, int R, tag c) {
        int len = R - L + 1;
        lzy[u] += c;
        t[u] += (2 * c.strt + c.diff * (len - 1)) * len >> 1;
        return;
    }
    inline void pushup(int u) {
        t[u] = t[u << 1] + t[u << 1 | 1];
        return;
    }
    inline void pushdown(int u, int L, int R) {
        int M = L + R >> 1;
        maketag(u << 1, L, M, lzy[u]);
        maketag(u << 1 | 1, M + 1, R, tag(lzy[u].strt + (M + 1 - L + 1) * lzy[u].diff, lzy[u].diff));
        lzy[u] = tag();
        return;
    }
    inline void build(int u, int L, int R) {
        lzy[u] = tag();
        if (L == R) {
            in >> t[u];
            p[L] = u;
        } else {
            int M = L + R >> 1;
            build(u << 1, L, M);
            build(u << 1 | 1, M + 1, R);
            pushup(u);
        }
        return;
    }
    inline void update(int u, int L, int R, int l, int r, tag c) {
        if (in_range(L, R, l, r)) {
            maketag(u, L, R, c);
        } else if (!out_range(L, R, l, r)) {
            int M = L + R >> 1;
            pushdown(u, L, R);
            update(u << 1, L, M, l, r, c);
            int rl = M + 1, rr = R;
//            update(u << 1 | 1, rl, rr, l, r, tag(c.strt + max(0ll, (rl - max(L, l))) * c.diff, c.diff));
//            自己推导
            if (rl <= r && l < L)
                update(u << 1 | 1, rl, rr, l, r, tag(c.strt + (rl - L) * c.diff, c.diff));
            else if (rl <= r && l >= rl)
                update(u << 1 | 1, rl, rr, l, r, c);
            else if (rl <= r)
                update(u << 1 | 1, rl, rr, l, r, tag(c.strt + (rl - l) * c.diff, c.diff));
            pushup(u);
        }
        return;
    }
    inline int query(int u, int L, int R, int k) {
        if (in_range(L, R, k, k))
            return t[u];
        if (out_range(L, R, k, k))
            return 0;
        pushdown(u, L, R);
        int M = L + R >> 1;
        return query(u << 1, L, M, k) + query(u << 1 | 1, M + 1, R, k);
    }
} I AK NOI;

signed main(signed argc, char const *argv[]) {
    in >> N >> Q;
    build(1, 1, N);//读入用了线段树递归特性
    int op, l, r;
    tag c;
    while (Q--) {
        in >> op;
        if (op == 1) {
            in >> l >> r >> c.strt >> c.diff;
//            for (int i = 1; i <= N; i++)
//                out << t[p[i]];
//            putchar(10);
            update(1, 1, N, l, r, c);
        } else {
            in >> l;
//            for (int i = 1; i <= N; i++)
            out << query(1, 1, N, l);
        }
    }
    return 0;
}

2024/11/13 18:31
加载中...