月赛2C
  • 板块灌水区
  • 楼主fsdgakjl
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/7/30 18:25
  • 上次更新2023/10/27 17:41:28
查看原帖
月赛2C
115110
fsdgakjl楼主2022/7/30 18:25

求一个靠谱的做法,或者帮调一下代码

我的做法大概是离线询问按 ww 升序排序,然后指针由小到大维护 xx 的变化值对前缀和的影响,用线段树维护子段和。

#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;
}
2022/7/30 18:25
加载中...