社区讨论

这份代码还有前途吗

P15325【MX-X24-T6】「RiOI-7」Stardust:RAY参与者 4已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@mlqrnxvw
此快照首次捕获于
2026/02/17 23:37
前天
此快照最后确认于
2026/02/18 00:23
昨天
查看原帖
77 pts,5e5 跑了 1.5s,感觉卡不太动了
CPP
#include <bits/stdc++.h>
using namespace std;
#define il inline
typedef long long ll;
const int N = 1e6 + 5; char buf[N], *p1, *p2;
#define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, N, stdin), p1 == p2) ? EOF : *p1++)
il int rd() { int x = 0; char c = 0; while (c < '0' || c > '9') c = gc; while (c >= '0' && c <= '9') x = x * 10 - '0' + c, c = gc; return x; }
int n, m, a[N], ps[N];
struct info { ll sl, sr, slr; il info(ll sl = 0, ll sr = 0, ll slr = 0): sl(sl), sr(sr), slr(slr) {} };
il info operator+(const info &a, const info &b) { return {a.sl + b.sl, a.sr + b.sr, a.slr + b.slr}; }
il info operator-(const info &a, const info &b) { return {a.sl - b.sl, a.sr - b.sr, a.slr - b.slr}; }
struct node { int mn, mx; info s; } t[N << 2];
#define lc p << 1
#define rc lc | 1
ll calcl(int p, int l, int r, int mn) {
	if (mn <= t[p].mn) return (ll)mn * (r - l + 1); if (mn >= ps[l]) return t[p].s.sl;
	if (l == r) return min(mn, ps[l]); int mid = l + r >> 1;
	if (mn <= t[lc].mn) return (ll)mn * (mid - l + 1) + calcl(rc, mid + 1, r, mn);
	return calcl(lc, l, mid, mn) + t[p].s.sl - t[lc].s.sl;
}
ll calcr(int p, int l, int r, int mx) {
	if (mx >= t[p].mx) return (ll)mx * (r - l + 1); if (mx <= ps[l]) return t[p].s.sr;
	if (l == r) return max(mx, ps[l]); int mid = l + r >> 1;
	if (mx >= t[lc].mx) return (ll)mx * (mid - l + 1) + calcr(rc, mid + 1, r, mx);
	return calcr(lc, l, mid, mx) + t[p].s.sr - t[lc].s.sr;
}
info calc(int p, int l, int r, int mn, int mx) {
	if (mn <= t[p].mn && mx >= t[p].mx) { ll len = r - l + 1; return {mn * len, mx * len, len * mn * mx}; }
	if (mn >= ps[l] && mx <= ps[l]) return t[p].s;
	if (l == r) { ll _mn = min(mn, ps[l]), _mx = max(mx, ps[l]); return {_mn, _mx, _mn * _mx}; }
	int mid = l + r >> 1; bool f1 = mn <= t[lc].mn, f2 = mx >= t[lc].mx;
	if (f1 && f2) { ll len = mid - l + 1; return info(mn * len, mx * len, len * mn * mx) + calc(rc, mid + 1, r, mn, mx); }
	if (!f1 && !f2) return calc(lc, l, mid, mn, mx) + (t[p].s - t[lc].s);
	if (!f2) { ll sr = calcr(lc, l, mid, mx); return info((ll)mn * (mid - l + 1), sr, mn * sr) + calc(rc, mid + 1, r, mn, t[lc].mx); }
	ll sl = calcl(lc, l, mid, mn); return info(sl, (ll)mx * (mid - l + 1), mx * sl) + calc(rc, mid + 1, r, t[lc].mn, mx);
}
il void psu(int p, int l, int r) {
	int mid = l + r >> 1; t[p].mn = min(t[lc].mn, t[rc].mn), t[p].mx = max(t[lc].mx, t[rc].mx);
	t[p].s = t[lc].s + calc(rc, mid + 1, r, t[lc].mn, t[lc].mx);
}
void build(int p, int l, int r) {
	if (l == r) return t[p] = {ps[l], ps[l], info(ps[l], ps[l], (ll)ps[l] * ps[l])}, void();
	int mid = l + r >> 1; build(lc, l, mid), build(rc, mid + 1, r), psu(p, l, r);
}
void upd(int p, int l, int r, int x) {
	if (l == r) return t[p] = {ps[l], ps[l], info(ps[l], ps[l], (ll)ps[l] * ps[l])}, void();
	int mid = l + r >> 1; x <= mid ? upd(lc, l, mid, x) : upd(rc, mid + 1, r, x), psu(p, l, r);
}
int mex(int p, int l, int r, int mn, int mx) {
	if (t[p].mn >= mn && t[p].mx <= mx) return n; if (l == r) return l; int mid = l + r >> 1;
	return t[lc].mn >= mn && t[lc].mx <= mx ? mex(rc, mid + 1, r, mn, mx) : mex(lc, l, mid, mn, mx);
} info tot;
void qry(int p, int l, int r, int L, int R, int &mn, int &mx) {
	if (L <= l && r <= R) return tot = tot + calc(p, l, r, mn, mx), mn = min(mn, t[p].mn), mx = max(mx, t[p].mx), void();
	int mid = l + r >> 1; if (L <= mid) qry(lc, l, mid, L, R, mn, mx); if (R > mid) qry(rc, mid + 1, r, L, R, mn, mx);
}
int main() {
	n = rd(), m = rd(); for (int i = 1; i <= n; i++) ps[a[i] = rd()] = i; build(1, 0, n - 1);
	while (m--) {
		int op = rd();
		if (op == 1) {
			int x = rd(), y = rd(), ax = a[x], ay = a[y];
			swap(a[x], a[y]), swap(ps[ax], ps[ay]), upd(1, 0, n - 1, ax), upd(1, 0, n - 1, ay);
		} else {
			int l = rd(), r = rd(), k = mex(1, 0, n - 1, l, r);
			if (k == 0) { cout << "0\n"; continue; }
			tot = info(0, 0, 0); int mn = 1e9, mx = 0; qry(1, 0, n - 1, 0, k - 1, mn, mx);
			cout << (r + 1) * tot.sl + (l - 1) * tot.sr - tot.slr - ll(r + 1) * (l - 1) * k << '\n';
		}
	}
}

// Niko 长得好像某个人,我没有想要 ky,但真的好像,我知道大家都不希望 Niko 被说像谁,所以这也是我上网冲浪这么多年来,第一次鼓起勇气忐忑的打着键盘,写下我最真实的评论:Niko 长得好像我老公

回复

9 条回复,欢迎继续交流。

正在加载回复...