现在不会TLE了,但还是WA了:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 0x3f3f3f3f;
const int MAX_N = 2e5 + 50;
int T, n, m, a[MAX_N];
#define ls(cur) cur << 1
#define rs(cur) cur << 1 | 1
namespace SegmentTree1 { // the case of a[i] <= x
long long sum[MAX_N << 2], vtag[MAX_N << 2];
int cnt[MAX_N << 2], stag[MAX_N << 2];
void pushup(int cur) {
sum[cur] = sum[ls(cur)] + sum[rs(cur)];
cnt[cur] = cnt[ls(cur)] + cnt[rs(cur)];
}
void mark(int cur, int sign, long long val) {
sum[cur] *= sign;
sum[cur] += cnt[cur] * val;
stag[cur] *= sign;
vtag[cur] += val;
}
void pushdown(int cur) {
if (stag[cur] != 1) {
mark(ls(cur), stag[cur], 0);
mark(rs(cur), stag[cur], 0);
stag[cur] = 1;
}
if (vtag[cur]) {
mark(ls(cur), 1, vtag[cur]);
mark(rs(cur), 1, vtag[cur]);
vtag[cur] = 0;
}
}
void build(int cur, int l, int r) {
stag[cur] = 1;
vtag[cur] = 0;
if (l == r) {
sum[cur] = cnt[cur] = 0;
return ;
}
int mid = l + r >> 1;
build(ls(cur), l, mid);
build(rs(cur), mid + 1, r);
pushup(cur);
}
void insert(int cur, int l, int r, int idx, int val) {
if (l == r) {
sum[cur] = val;
cnt[cur] = 1;
return ;
}
pushdown(cur);
int mid = l + r >> 1;
if (idx <= mid)
insert(ls(cur), l, mid, idx, val);
else
insert(rs(cur), mid + 1, r, idx, val);
pushup(cur);
}
void modify(int cur, int l, int r, int L, int R, int val) {
if (L <= l && r <= R) {
mark(cur, -1, val);
return ;
}
pushdown(cur);
int mid = l + r >> 1;
if (L <= mid)
modify(ls(cur), l, mid, L, R, val);
if (mid + 1 <= R)
modify(rs(cur), mid + 1, r, L, R, val);
pushup(cur);
}
long long query(int cur, int l, int r, int L, int R) {
if (L <= l && r <= R)
return sum[cur];
pushdown(cur);
int mid = l + r >> 1;
long long res = 0;
if (L <= mid)
res += query(ls(cur), l, mid, L, R);
if (mid + 1 <= R)
res += query(rs(cur), mid + 1, r, L, R);
return res;
}
};
namespace SegmentTree2 { // the case of a[i] > x
long long sum[MAX_N << 2], tag[MAX_N << 2];
int cnt[MAX_N << 2], mn[MAX_N << 2];
void pushup(int cur) {
sum[cur] = sum[ls(cur)] + sum[rs(cur)];
cnt[cur] = cnt[ls(cur)] + cnt[rs(cur)];
mn[cur] = min(mn[ls(cur)], mn[rs(cur)]);
}
void mark(int cur, long long val) {
sum[cur] -= cnt[cur] * val;
mn[cur] -= bool(cnt[cur]) * val;
tag[cur] += val;
}
void pushdown(int cur) {
if (tag[cur]) {
mark(ls(cur), tag[cur]);
mark(rs(cur), tag[cur]);
tag[cur] = 0;
}
}
void build(int cur, int l, int r, int val[]) {
tag[cur] = 0;
if (l == r) {
sum[cur] = mn[cur] = val[l];
cnt[cur] = 1;
return ;
}
int mid = l + r >> 1;
build(ls(cur), l, mid, val);
build(rs(cur), mid + 1, r, val);
pushup(cur);
}
void modify(int cur, int l, int r, int L, int R, int val) {
if (l == r && mn[cur] <= val) {
SegmentTree1::insert(1, 1, n, l, mn[cur]);
sum[cur] = cnt[cur] = 0, mn[cur] = INF;
return ;
}
if (L <= l && r <= R && mn[cur] > val) {
mark(cur, val);
return ;
}
pushdown(cur);
int mid = l + r >> 1;
if (L <= mid)
modify(ls(cur), l, mid, L, R, val);
if (mid + 1 <= R)
modify(rs(cur), mid + 1, r, L, R, val);
pushup(cur);
}
long long query(int cur, int l, int r, int L, int R) {
if (L <= l && r <= R)
return sum[cur];
pushdown(cur);
int mid = l + r >> 1;
long long res = 0;
if (L <= mid)
res += query(ls(cur), l, mid, L, R);
if (mid + 1 <= R)
res += query(rs(cur), mid + 1, r, L, R);
return res;
}
};
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> T;
while (T--) {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
SegmentTree1::build(1, 1, n);
SegmentTree2::build(1, 1, n, a);
for (int opt, l, r, x; m--; ) {
cin >> opt >> l >> r;
if (opt == 1) {
cin >> x;
SegmentTree2::modify(1, 1, n, l, r, x);
SegmentTree1::modify(1, 1, n, l, r, x);
} else {
long long ans1 = SegmentTree1::query(1, 1, n, l, r);
long long ans2 = SegmentTree2::query(1, 1, n, l, r);
cout << ans1 + ans2 << '\n';
}
}
}
return 0;
}
最新发布