线段树
无差分
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;
}