记录编号 589000 评测结果 AAAAAAAAAA
题目名称 雨滴之歌 最终得分 100
用户昵称 Gravataryrtiop 是否通过 通过
代码语言 C++ 运行时间 0.907 s
提交时间 2024-07-02 15:06:19 内存使用 51.65 MiB
显示代码纯文本
#include <bits/stdc++.h>
#define pb emplace_back
#define fir first
#define sec second
#define Tp template <typename T>

using i64 = long long;
using pii = std::pair<int, int>;

constexpr int maxn = 2e5 + 5, inf = 1e9 + 5;
int n, m, a[maxn], b[maxn];

Tp void chkmin(T& x, T y) { x = y < x ? y : x; return; }
Tp void chkmax(T& x, T y) { x = y > x ? y : x; return; }

struct ST1 {
	int n, lg[maxn], st[20][maxn];
	void init(int _n, int* a) {
		n = _n;
		for (int i = 1; i <= n; ++i) {
			st[0][i] = a[i];
		}
		for (int i = 2; i <= n; ++i) {
			lg[i] = lg[i >> 1] + 1;
		}
		for (int k = 1; (1 << k) <= n; ++k) {
			for (int i = 1; i + (1 << k) - 1 <= n; ++i) {
				st[k][i] = std::min(st[k - 1][i], st[k - 1][i + (1 << k - 1)]);
			}
		}
		return;
	}
	int RMQ(int l, int r) {
		if (l > r) std::swap(l, r);
		int k = lg[r - l + 1];
		return std::min(st[k][l], st[k][r - (1 << k) + 1]);
	}
} mna, mnb;

struct ST2 {
	int n, lg[maxn], st[20][maxn];
	void init(int _n, int* a) {
		n = _n;
		for (int i = 1; i <= n; ++i) {
			st[0][i] = a[i];
		}
		for (int i = 2; i <= n; ++i) {
			lg[i] = lg[i >> 1] + 1;
		}
		for (int k = 1; (1 << k) <= n; ++k) {
			for (int i = 1; i + (1 << k) - 1 <= n; ++i) {
				st[k][i] = std::max(st[k - 1][i], st[k - 1][i + (1 << k - 1)]);
			}
		}
		return;
	}
	int RMQ(int l, int r) {
		if (l > r) std::swap(l, r);
		int k = lg[r - l + 1];
		return std::max(st[k][l], st[k][r - (1 << k) + 1]);
	}
} mxa, mxb;

int S[maxn], T[maxn], c[maxn];

void add(int x, int y) {
	if (!x) return;
	for (; x <= n; x += x & -x) {
		c[x] += y;
	}
	return;
}
int query(int x) {
	int ans = 0;
	for (; x > 0; x -= x & -x) {
		ans += c[x];
	}
	return ans;
}

i64 solve(int* a, int* b, int l, int r) {
	i64 ans = 0;
	for (int i = r; i >= l; --i) {
		ans += query(a[i]);
		add(b[i], 1);
	}
	for (int i = l; i <= r; ++i) {
		add(b[i], -1);
	}
	return ans;
}

int main() {
	freopen("expansion.in", "r", stdin);
	freopen("expansion.out", "w", stdout);
	std::cin.tie(nullptr)->sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
	}
	for (int i = 1; i <= m; ++i) {
		std::cin >> b[i];
	}
	mna.init(n, a);
	mnb.init(m, b);
	mxa.init(n, a);
	mxb.init(m, b);
	int mx = 0, dt = 0;
	for (int i = n; i >= 1; --i) {
		auto upd = [&]() {
			S[i] = mx = 0;
			return;
		};
		if (a[i] + mxb.RMQ(1, m) < 0) {
			mx = S[i] = 0;
		} else if (a[i] + mnb.RMQ(1, m) >= 0) {
			chkmax(mx, i);
			S[i] = mx;
			++dt;
		} else {
			if (i == n || mxa.RMQ(i + 1, n) < a[i]) {
				// upd();
				continue;
			}
			int l = i + 1, r = n;
			while (l <= r) {
				int mid = (l + r) >> 1;
				if (mxa.RMQ(i + 1, mid) >= a[i]) {
					r = mid - 1;
				} else {
					l = mid + 1;
				}
			}
			if (mxb.RMQ(1, m) + mna.RMQ(i, l) < 0) {
				// upd();
				continue;
			}
			int ql = 1, qr = m;
			while (ql <= qr) {
				int mid = (ql + qr) >> 1;
				if (mxb.RMQ(1, mid) + mna.RMQ(i, l) >= 0) {
					qr = mid - 1;
				} else {
					ql = mid + 1;
				}
			}
			if (a[i] + mnb.RMQ(1, ql) >= 0) {
				S[i] = S[l];
			} else {
				S[i] = 0;
			}
		}
	}
	int mn = n + 1;
	std::fill(T + 1, T + 1 + n, n + 1);
	for (int i = 1; i <= n; ++i) {
		auto upd = [&]() {
			T[i] = mn = n + 1;
			return;
		};
		if (a[i] + mxb.RMQ(1, m) < 0) {
			T[i] = mn = n + 1;
		} else if (a[i] + mnb.RMQ(1, m) >= 0) {
			chkmin(mn, i);
			T[i] = mn;
		} else {
			if (i == 1 || mxa.RMQ(1, i - 1) < a[i]) {
				// upd();
				continue;
			}
			int l = 1, r = i - 1;
			while (l <= r) {
				int mid = (l + r) >> 1;
				if (mxa.RMQ(mid, i - 1) >= a[i]) {
					l = mid + 1;
				} else {
					r = mid - 1;
				}
			}
			l = r;
			if (mxb.RMQ(1, m) + mna.RMQ(l, i) < 0) {
				// upd();
				continue;
			}
			int ql = 1, qr = m;
			while (ql <= qr) {
				int mid = (ql + qr) >> 1;
				if (mxb.RMQ(mid, m) + mna.RMQ(l, i) >= 0) {
					ql = mid + 1;
				} else {
					qr = mid - 1;
				}
			}
			ql = qr;
			if (a[i] + mnb.RMQ(ql, m) >= 0) {
				T[i] = T[l];
			} else {
				T[i] = n + 1;
				// upd();
			}
		}
	}
	i64 ans = solve(S, T, 1, n) + dt;
	int lst = 0;
	for (int i = 1; i <= n; ++i) {
		if (a[i] + mnb.RMQ(1, m) >= 0) {
			ans -= solve(S, T, lst + 1, i - 1);
			lst = i;
		}
	}
	ans -= solve(S, T, lst + 1, n);
	std::cout << ans << '\n';
	return 0;
}