什么是矢?这就是矢
Easy problem I HDU - 7284
思路
没有任何思维,如果你想简单点做这个题,那么你还是止步吧,这个题目直接用最简单的思路,分类讨论,按照绝对值内正负分别建立线段树,由于 x 不减,所以从一个树跳到另一个树最多一次,总时间复杂度 \(O((n + m)logn)\)
由于思路太短了,所以我放个图凑个数(

code
代码长的吓死你
#include <iostream>
#define int long long
using namespace std;
const int MaxN = 2e5 + 10;
int a[MaxN], n, m, t;
namespace seg2 {
int d[MaxN << 2], tag1[MaxN << 2], tag2[MaxN << 2], len[MaxN << 2];
void build(int l = 1, int r = n, int p = 1) {
tag1[p] = tag2[p] = 0;
if (l == r) {
d[p] = len[p] = 0;
return;
}
int mid = l + r >> 1;
build(l, mid, p << 1), build(mid + 1, r, p << 1 | 1);
d[p] = d[p << 1] + d[p << 1 | 1], len[p] = len[p << 1] + len[p << 1 | 1];
}
void addtag1(int p) {
if (len[p]) d[p] = -d[p], tag2[p] = -tag2[p], tag1[p] ^= 1;
}
void addtag2(int p, int w) {
if (len[p]) d[p] += len[p] * w, tag2[p] += w;
}
void pd(int p) {
if (tag1[p]) addtag1(p << 1), addtag1(p << 1 | 1), tag1[p] = 0;
if (tag2[p]) addtag2(p << 1, tag2[p]), addtag2(p << 1 | 1, tag2[p]), tag2[p] = 0;
}
void update(int p) {
d[p] = d[p << 1] + d[p << 1 | 1], len[p] = len[p << 1] + len[p << 1 | 1];
}
void modify(int pl, int pr, int w, int l = 1, int r = n, int p = 1) {
if (!len[p]) return;
if (pl <= l && r <= pr) {
return addtag1(p), addtag2(p, w);
}
if (pl > r || pr < l) return;
pd(p);
int mid = l + r >> 1;
modify(pl, pr, w, l, mid, p << 1), modify(pl, pr, w, mid + 1, r, p << 1 | 1), update(p);
}
void mao(int k, int w, int l = 1, int r = n, int p = 1) {
if (l == r) {
d[p] = w, len[p] = 1;
return;
}
pd(p);
int mid = l + r >> 1;
if (k <= mid) mao(k, w, l, mid, p << 1);
if (k > mid) mao(k, w, mid + 1, r, p << 1 | 1);
update(p);
}
int query(int pl, int pr, int l = 1, int r = n, int p = 1) {
if (!len[p]) return 0;
if (pl <= l && r <= pr) return d[p];
if (pl > r || pr < l) return 0;
pd(p);
int mid = l + r >> 1;
return query(pl, pr, l, mid, p << 1) + query(pl, pr, mid + 1, r, p << 1 | 1);
}
};
namespace seg1 {
int d[MaxN << 2], tag[MaxN << 2], mix[MaxN << 2], len[MaxN << 2];
void build(int l = 1, int r = n, int p = 1) {
tag[p] = 0;
if (l == r) {
d[p] = mix[p] = a[l], len[p] = 1;
return;
}
int mid = l + r >> 1;
build(l, mid, p << 1), build(mid + 1, r, p << 1 | 1);
d[p] = d[p << 1] + d[p << 1 | 1], mix[p] = min(mix[p << 1], mix[p << 1 | 1]), len[p] = len[p << 1] + len[p << 1 | 1];
}
void addtag(int p, int w) {
if (len[p]) d[p] -= w * len[p], mix[p] -= w, tag[p] += w;
}
void pd(int p) {
addtag(p << 1, tag[p]), addtag(p << 1 | 1, tag[p]), tag[p] = 0;
}
void update(int p) {
d[p] = d[p << 1] + d[p << 1 | 1], mix[p] = min(mix[p << 1], mix[p << 1 | 1]), len[p] = len[p << 1] + len[p << 1 | 1];
}
void modify(int pl, int pr, int w, int l = 1, int r = n, int p = 1) {
if (!len[p]) return;
if (pl > r || pr < l) return;
if (l == r && mix[p] <= w) {
len[p] = d[p] = 0;
return seg2::mao(l, mix[p]), void(mix[p] = 1e18);
}
if (pl <= l && r <= pr) {
if (mix[p] <= w) {
pd(p);
int mid = l + r >> 1;
return modify(pl, pr, w, l, mid, p << 1), modify(pl, pr, w, mid + 1, r, p << 1 | 1), update(p);
}
return addtag(p, w);
}
pd(p);
int mid = l + r >> 1;
modify(pl, pr, w, l, mid, p << 1), modify(pl, pr, w, mid + 1, r, p << 1 | 1), update(p);
}
int query(int pl, int pr, int l = 1, int r = n, int p = 1) {
if (!len[p]) return 0;
if (pl <= l && r <= pr) return d[p];
if (pl > r || pr < l) return 0;
pd(p);
int mid = l + r >> 1;
return query(pl, pr, l, mid, p << 1) + query(pl, pr, mid + 1, r, p << 1 | 1);
}
}; // namespace seg1
signed main() {
ios::sync_with_stdio(0), cin.tie(0);
for (cin >> t; t; t--) {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
seg1::build(), seg2::build();
for (int op, l, r, x; m; m--) {
cin >> op >> l >> r;
if (op == 1) {
cin >> x;
seg1::modify(l, r, x);
seg2::modify(l, r, x);
} else {
cout << seg1::query(l, r) + seg2::query(l, r) << '\n';
}
}
}
return 0;
}

浙公网安备 33010602011771号