求一个靠谱的做法,或者帮调一下代码
我的做法大概是离线询问按 w 升序排序,然后指针由小到大维护 x 的变化值对前缀和的影响,用线段树维护子段和。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
const ll Lnf = 0x3f3f3f3f3f3f3f3fll;
int read() {
int res = 0, ch = getchar(), f = 1;
while(!(ch >= '0' && ch <= '9') && ch != EOF) {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
res = (res << 3) + (res << 1) + (ch - '0');
ch = getchar();
}
return res * f;
}
ll S, n, q, w, b1, b2, incr, decr;
ll x[maxn], id[maxn], val[maxn], sum[maxn];
bool compare(int i, int j) {
return x[i] < x[j];
}
struct Query {
int w, l, h, id;
vector<int> il, ih;
bool operator < (const Query &tmp) const {
return w < tmp.w;
}
}qu[maxn];
ll ans[maxn];
vector<int> sm1, sm2, sm3, bi1, bi2, bi3;
int psm1, psm2, psm3, pbi1, pbi2, pbi3;
bool vis[maxn];
struct SegMent {
ll mi, ma, tag;
}tree[4 * maxn];
inline int ls(int p) {return p << 1;}
inline int rs(int p) {return p << 1 | 1;}
void pushup(int p) {
tree[p].mi = min(tree[ls(p)].mi, tree[rs(p)].mi);
tree[p].ma = max(tree[ls(p)].ma, tree[rs(p)].ma);
}
void pushdown(int p) {
if(tree[p].tag == 0) return;
tree[ls(p)].mi += tree[p].tag;
tree[ls(p)].ma += tree[p].tag;
tree[ls(p)].tag += tree[p].tag;
tree[rs(p)].mi += tree[p].tag;
tree[rs(p)].ma += tree[p].tag;
tree[rs(p)].tag += tree[p].tag;
tree[p].tag = 0;
}
void build(int p, int l, int r) {
if(l == r) {
tree[p].mi = tree[p].ma = sum[l];
return;
}
int mid = (l + r) >> 1;
build(ls(p), l, mid), build(rs(p), mid + 1, r);
pushup(p);
}
void update(int p, int l, int r, int ql, int qr, int v) {
if(l == ql && r == qr) {
tree[p].tag += v;
tree[p].mi += v, tree[p].ma += v;
return;
}
pushdown(p);
int mid = (l + r) >> 1;
if(mid >= qr) update(ls(p), l, mid, ql, qr, v);
else if(mid + 1 <= ql) update(rs(p), mid + 1, r, ql, qr, v);
else update(ls(p), l, mid, ql, mid, v), update(rs(p), mid + 1, r, mid + 1, qr, v);
pushup(p);
}
ll query_ma(int p, int l, int r, int ql, int qr) {
if(ql > qr) return -1e9;
if(l == ql && r == qr) {
return tree[p].ma;
}
pushdown(p);
int mid = (l + r) >> 1;
if(mid >= qr) return query_ma(ls(p), l, mid, ql, qr);
else if(mid + 1 <= ql) return query_ma(rs(p), mid + 1, r, ql, qr);
else return max(query_ma(ls(p), l, mid, ql, mid), query_ma(rs(p), mid + 1, r, mid + 1, qr));
}
ll query_mi(int p, int l, int r, int ql, int qr) {
if(ql > qr) return 1e9;
if(l == ql && r == qr) {
return tree[p].mi;
}
pushdown(p);
int mid = (l + r) >> 1;
if(mid >= qr) return query_mi(ls(p), l, mid, ql, qr);
else if(mid + 1 <= ql) return query_mi(rs(p), mid + 1, r, ql, qr);
else return min(query_mi(ls(p), l, mid, ql, mid), query_mi(rs(p), mid + 1, r, mid + 1, qr));
}
int main() {
S = read();
n = read(), q = read(), w = read(), b1 = read(), b2 = read(), incr = read(), decr = read();
for(int i = 1;i <= n;i++) {
x[i] = read(), id[i] = i;
}
sort(id + 1, id + n + 1, compare);
int curw = w, t = 0;
for(int i = 1;i <= q;i++) {
int op = read(), nl, nh, nw;
if(op == 1) {
nl = read(), nh = read();
++t, qu[t].w = curw, qu[t].l = nl, qu[t].h = nh, qu[t].id = t;
for(int i = 1;i <= nl;i++) {
int p = read();
qu[t].il.push_back(p);
}
for(int i = 1;i <= nh;i++) {
int p = read();
qu[t].ih.push_back(p);
}
}
else {
nw = read();
curw = nw;
}
}
q = t;
sort(qu + 1, qu + t + 1);
int smw = qu[1].w;
int p = 0;// 对于当前的 w, id[0, p - 1] <= w, id[p, n] > w
for(int i = 1;i <= n;i++) {
int pos = id[i];
if(x[pos] > smw) {
if(w < x[pos] - b2) val[pos] = decr, bi1.push_back(i);
else if(w >= x[pos] - b2 && w < x[pos] - b1) val[pos] = 0, bi2.push_back(i);
else val[pos] = incr;
}
else {
p = i;
if(w <= x[pos] + b1) val[pos] = incr, sm1.push_back(i), vis[pos] = true;
else if(w > x[pos] + b1 && w <= x[pos] + b2) val[pos] = 0, sm2.push_back(i), vis[pos] = true;
else val[pos] = decr;
}
}
for(int i = 1;i <= n;i++) {
sum[i] = sum[i - 1] + val[i];
}
build(1, 0, n);
p++;
for(int i = 1;i <= q;i++) {
int w = qu[i].w, l = qu[i].l, qid = qu[i].id;
while(p <= n && x[id[p]] <= w) {
if(w <= x[id[p]] + b1) {
update(1, 0, n, id[p], n, +incr - val[id[p]]);
sm1.push_back(p);
}
else if(w > x[id[p]] + b1 && w <= x[id[p]] + b2) {
update(1, 0, n, id[p], n, +0 - val[id[p]]);
sm2.push_back(p);
}
else {
update(1, 0, n, id[p], n, +decr - val[id[p]]);
}
vis[id[p]] = true, sm1.push_back(p), p++;
}
while(psm1 < (int)sm1.size() && w > x[id[sm1[psm1]]] + b1 && w <= x[id[sm1[psm1]]] + b2) { // incr -> 0
update(1, 0, n, id[sm1[psm1]], n, +0 - incr);
sm2.push_back(sm1[psm1]), psm1++;
}
while(psm1 < (int)sm1.size() && w > x[id[sm1[psm1]]] + b2) {
update(1, 0, n, id[sm1[psm1]], n, +decr - incr);
psm1++;
}
while(psm2 < (int)sm2.size() && w > x[id[sm2[psm2]]] + b2) { // 0 -> decr
update(1, 0, n, id[sm2[psm2]], n, +decr - 0);
psm2++;
}
while(pbi1 < (int)bi1.size()) {
if(vis[id[bi1[pbi1]]] == true) {
pbi1++;
continue;
}
else if(w >= x[id[bi1[pbi1]]] - b2 && w < x[id[bi1[pbi1]]] - b1) { // decr -> 0
update(1, 0, n, id[bi1[pbi1]], n, +0 - decr);
val[id[bi1[pbi1]]] = 0;
bi2.push_back(bi1[pbi1]), pbi1++;
}
else if(w >= x[id[bi1[pbi1]]] - b1) {
val[id[bi1[pbi1]]] = incr;
update(1, 0, n, id[bi1[pbi1]], n, +incr - decr);
pbi1++;
}
else {
break;
}
}
while(pbi2 < (int)bi2.size()) {
if(vis[id[bi2[pbi2]]] == true) {
pbi2++;
continue;
}
else if(w >= x[id[bi2[pbi2]]] - b1) { // 0 -> incr
val[id[bi2[pbi2]]] = incr;
update(1, 0, n, id[bi2[pbi2]], n, +incr - 0);
pbi2++;
}
else {
break;
}
}
ll res = -Lnf;
for(int j = 1;j <= l;j++) {
int pl = lower_bound(qu[i].ih.begin(), qu[i].ih.end(), qu[i].il[j - 1]) - qu[i].ih.begin() - 1;
int pr = lower_bound(qu[i].ih.begin(), qu[i].ih.end(), qu[i].il[j - 1]) - qu[i].ih.begin();
int ql = (pl == -1) ? 0 : qu[i].ih[pl], qr = (pr == (int)qu[i].ih.size()) ? (n + 1) : qu[i].ih[pr];
res = max(res, query_ma(1, 0, n, qu[i].il[j - 1], qr - 1) - query_mi(1, 0, n, ql, qu[i].il[j - 1] - 1));
}
ans[qid] = res;
}
for(int i = 1;i <= q;i++) {
printf("%lld\n", ans[i]);
}
return 0;
}