比赛 2024.5.23练习赛 评测结果 AAAAAAAAAA
题目名称 新年快乐! 最终得分 100
用户昵称 yrtiop 运行时间 5.082 s
代码语言 C++ 内存使用 9.07 MiB
提交时间 2024-05-23 18:58:28
显示代码纯文本
#include <bits/stdc++.h>
#define pb emplace_back
#define fir first
#define sec second

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

constexpr int maxn = 1e5 + 5;
constexpr int S = 500;
i64 tag[maxn], a[maxn];
int n, L[maxn], R[maxn], bel[maxn];

struct info {
	i64 v;
	int idx;
	info() { v = idx = 0; }
	info(int idx, i64 v) : idx(idx), v(v) {}
	bool operator < (const info& rhs) const {
		return v < rhs.v;
	}
} b[maxn];

int main() {
	freopen("dss.in", "r", stdin);
	freopen("dss.out", "w", stdout);
	std::cin.tie(nullptr)->sync_with_stdio(false);
	std::cin >> n;
	for (int i = 1; i <= n; ++i)
		std::cin >> a[i];
	int m;
	std::cin >> m;
	int bn = (n - 1) / S + 1;
	for (int i = 1; i <= bn; ++i) {
		L[i] = R[i - 1] + 1;
		R[i] = std::min(n, R[i - 1] + S);
		std::fill(bel + L[i], bel + R[i] + 1, i);
		tag[i] = 0;
	}
	for (int i = 1; i <= n; ++i)
		b[i] = info(i, a[i]);
	for (int i = 1; i <= bn; ++i)
		std::sort(b + L[i], b + R[i] + 1, [&](const info& lhs, const info& rhs) {
			return lhs.v < rhs.v;
		});
	auto add_blk = [&](int p, int l, int r, i64 v) -> void {
		for (int i = L[p]; i <= R[p]; ++i) {
			if (l <= b[i].idx && b[i].idx <= r) {
				b[i].v += v;
			}
		}
		std::sort(b + L[p], b + R[p] + 1);
		return;
	};
	auto add = [&](int l, int r, i64 v) -> void {
		int p = bel[l], q = bel[r];
		if (p == q) {
			return add_blk(p, l, r, v);
		}
		add_blk(p, l, R[p], v);
		add_blk(q, L[q], r, v);
		for (int i = p + 1; i < q; ++i)
			tag[i] += v;
		return;
	};
	auto qry_blk = [&](int p, int l, int r, i64 k) -> int {
		int ans = 0;
		for (int i = L[p]; i <= R[p]; ++i)
			if (l <= b[i].idx && b[i].idx <= r) ans += b[i].v + tag[p] <= k;
		return ans;
	};
	auto query = [&](int l, int r, i64 k) -> int {
		int p = bel[l], q = bel[r], ans = 0;
		if (p == q) {
			return qry_blk(p, l, r, k);
		}
		ans = qry_blk(p, l, R[p], k) + qry_blk(q, L[q], r, k);
		for (int i = p + 1; i < q; ++i) {
			int ql = L[i], qr = R[i], mid;
			while (ql <= qr) {
				mid = (ql + qr) >> 1;
				if (b[mid].v + tag[i] > k) {
					qr = mid - 1;
				} else {
					ql = mid + 1;
				}
			}
			ans += qr - L[i] + 1;
		}
		return ans;
	};
	while (m--) {
		int opt, x, y;
		i64 z;
		std::cin >> opt >> x >> y >> z;
		if (opt == 1) {
			add(x, y, z);
		} else {
			std::cout << query(x, y, z) << '\n';
		}
	}
	return 0;
}