15 pts 吉司机线段树求条,玄关
查看原帖
15 pts 吉司机线段树求条,玄关
833737
Lyw_and_Segment_Tree楼主2024/12/3 13:52

rt,在几乎是照搬 OI wiki 上吉司机线段树的情况下,只有 15 pts,code :

#include <bits/stdc++.h>
#define ll long long
#define db double
#define inf 1000000000000000000ll
#define endl "\n"

namespace fastio {
	char buf[1 << 21], *p1 = buf, *p2 = buf;
	
	const ll getc() {
	    return p1 == p2 && ( p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1 ++;
	}
	
	const ll read() {
		ll x = 0, f = 1;
		
		char ch = getc();
		
		while (ch < '0' || ch > '9') {
			if (ch == '-') f = -1; ch = getc();
		}
		
		while (ch >= '0' && ch <= '9') {
			x = (x << 1) + (x << 3) + (ch ^ 48), ch = getc();
		}
		
		return x * f;
	}
	
	const void write(ll x) {
		if (x < 0) {
			putchar('-'), x = -x;
		}
		
	    ll sta[35], top = 0;
	    
	    do {
	        sta[top++] = x % 10, x /= 10;
	    } while (x);
	    
	    while (top) putchar(sta[--top] + 48);
	}
}

using namespace std;

ll n, q, a[500005], opt, l, r, x;

struct segment {
	ll l, r, len, sum, mx, mx2, mn, mn2, cmx, cmn, tmx, tmn, tad;
} w[2000005] ;

void pushup(ll u) {
	w[u].sum = w[u * 2].sum + w[u * 2 + 1].sum;

	if (w[u * 2].mx == w[u * 2 + 1].mx) {
		w[u].mx = w[u * 2].mx, w[u].cmx = w[u * 2].cmx + w[u * 2 + 1].cmx;
		w[u].mx2 = max(w[u * 2].mx2, w[u * 2 + 1].mx2);
	} else if (w[u * 2].mx > w[u * 2 + 1].mx) {
		w[u].mx = w[u * 2].mx, w[u].cmx = w[u * 2].cmx;
		w[u].mx2 = max(w[u * 2].mx2, w[u * 2 + 1].mx);
	} else {
		w[u].mx = w[u * 2 + 1].mx, w[u].cmx = w[u * 2 + 1].cmx;
		w[u].mx2 = max(w[u * 2].mx, w[u * 2 + 1].mx2);
	}

	if (w[u * 2].mn == w[u * 2 + 1].mn) {
		w[u].mn = w[u * 2].mn, w[u].cmn = w[u * 2].cmn + w[u * 2 + 1].cmn;
		w[u].mx2 = min(w[u * 2].mn2, w[u * 2 + 1].mn2);
	} else if (w[u * 2].mn < w[u * 2 + 1].mn) {
		w[u].mn = w[u * 2].mn, w[u].cmn = w[u * 2].cmn;
		w[u].mn2 = min(w[u * 2].mn2, w[u * 2 + 1].mn);
	} else {
		w[u].mn = w[u * 2 + 1].mn, w[u].cmn = w[u * 2 + 1].cmn;
		w[u].mn2 = min(w[u * 2].mn, w[u * 2 + 1].mn2);
	}
}

void build(ll u, ll l, ll r) {
	w[u].l = l, w[u].r = r, w[u].len = r - l + 1;

	w[u].tmn = inf, w[u].tmx = -inf;

	if (l == r) {
		w[u].sum = w[u].mx = w[u].mn = a[l];

		w[u].mx2 = -inf, w[u].mn2 = inf;

		w[u].cmx = w[u].cmn = 1;

		return ;
	}

	ll mid = l + ((r - l) >> 1);

	build(u * 2, l, mid), build(u * 2 + 1, mid + 1, r);

	pushup(u);
}

void push_add(ll u, ll x) {
	w[u].sum += w[u].len * x, w[u].mx += x, w[u].mn += x;

	if (w[u].mx2 != -inf) w[u].mx2 += x; 
	if (w[u].mn2 != inf) w[u].mn2 += x; 
	if (w[u].tmx != -inf) w[u].tmx += x; 
	if (w[u].tmn != inf) w[u].tmn += x; 

	w[u].tad += x;
}

void push_min(ll u, ll v) {
	// 注意比较 $\max$ 标记
	if (w[u].mx <= v) return;
	
	w[u].sum += (v - w[u].mx) * w[u].cmx;

	if (w[u].mn2 == w[u].mx) w[u].mn2 = v;  // !!!
	if (w[u].mn == w[u].mx) w[u].mn = v;    // !!!!!
	if (w[u].tmx > v) w[u].tmx = v;        // 更新取 $\max$ 标记
	
	w[u].mx = v, w[u].tmn = v;
}

void push_max(ll u, ll x) {
	if (w[u].mn > x) return;

	w[u].sum += (x - w[u].mn) * w[u].cmn;

	if (w[u].mx2 == w[u].mn) w[u].mx2 = x;
	if (w[u].mx == w[u].mn) w[u].mx = x;
	if (w[u].tmn < x) w[u].tmn = x;

	w[u].mn = x, w[u].tmx = x;
}

void pushdown(ll u) {
	push_add(u * 2, w[u].tad), push_add(u * 2 + 1, w[u].tad);
	
	if (w[u].tmx != -inf) push_max(u * 2, w[u].tmx), push_max(u * 2 + 1, w[u].tmx);
	if (w[u].tmn != inf) push_min(u * 2, w[u].tmn), push_min(u * 2 + 1, w[u].tmn);
	
	w[u].tad = 0, w[u].tmx = -inf, w[u].tmn = inf;
}

void add(ll u) {
	if (l <= w[u].l && w[u].r <= r) {
		push_add(u, x); return ;
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1);

	if (l <= mid) {
		add(u * 2);
	}

	if (r > mid) {
		add(u * 2 + 1);
	}

	pushup(u);
}

void tomin(ll u) {
	if (w[u].mx <= x) {
		return ;
	}

	if (l <= w[u].l && w[u].r <= r) {
		if (w[u].mx2 < x) {
			push_min(u, x); return ;
		}
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1);

	if (l <= mid) {
		tomin(u * 2);
	}

	if (r > mid) {
		tomin(u * 2 + 1);
	}

	pushup(u);
}

void tomax(ll u) {
	if (w[u].mn >= x) {
		return ;
	}

	if (l <= w[u].l && w[u].r <= r) {
		if (w[u].mn2 > x) {
			push_max(u, x); return ;
		}
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1);

	if (l <= mid) {
		tomax(u * 2);
	}

	if (r > mid) {
		tomax(u * 2 + 1);
	}

	pushup(u);
}

ll qsum(ll u) {
	if (l <= w[u].l && w[u].r <= r) {
		return w[u].sum;
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1), res = 0;

	if (l <= mid) {
		res += qsum(u * 2);
	}

	if (r > mid) {
		res += qsum(u * 2 + 1);
	}

	return res;
}

ll qmax(ll u) {
	if (l <= w[u].l && w[u].r <= r) {
		return w[u].mx;
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1), res = LLONG_MIN;

	if (l <= mid) {
		res = max(res, qmax(u * 2));
	}

	if (r > mid) {
		res = max(res, qmax(u * 2 + 1));
	}

	return res;
}

ll qmin(ll u) {
	if (l <= w[u].l && w[u].r <= r) {
		return w[u].mn;
	}

	pushdown(u);

	ll mid = w[u].l + ((w[u].r - w[u].l) >> 1), res = LLONG_MAX;

	if (l <= mid) {
		res = min(res, qmin(u * 2));
	}

	if (r > mid) {
		res = min(res, qmin(u * 2 + 1));
	}

	return res;
}

int main() {
	n = fastio::read();

	for (ll i = 1; i <= n; i++) a[i] = fastio::read();

	build(1, 1, n);

	q = fastio::read();

	while (q--) {
		opt = fastio::read(), l = fastio::read(), r = fastio::read();

		if (opt == 1) {
			x = fastio::read(), add(1);
		} else if (opt == 2) {
			x = fastio::read(), tomax(1);
		} else if (opt == 3) {
			x = fastio::read(), tomin(1);
		} else if (opt == 4) {
			fastio::write(qsum(1)), puts("");
		} else if (opt == 5) {
			fastio::write(qmax(1)), puts("");
		} else {
			fastio::write(qmin(1)), puts("");
		}
	}
}

自认为写的没问题,求条。

2024/12/3 13:52
加载中...