Submission #1364410

#TimeUsernameProblemLanguageResultExecution timeMemory
1364410jinhan814Grilled Bottle (KAISTRUN26SPRING_D)C++20
100 / 100
241 ms18108 KiB
#include <bits/stdc++.h>
using namespace std;

using i64 = long long;

struct segtree {
	segtree(int n) : sz(1 << (__lg(n - 1 | 1) + 1)), tree(sz << 1), lazy(sz << 1) {}
	void update(int l, int r, int x) {
		auto rec = [&](const auto& self, int node, int node_l, int node_r) -> void {
			push(node);
			if (node_r < l || r < node_l) return;
			if (l <= node_l && node_r <= r) {
				lazy[node] += x;
				push(node);
				return;
			}
			int mid = (node_l + node_r) / 2;
			self(self, node << 1, node_l, mid);
			self(self, node << 1 | 1, mid + 1, node_r);
			tree[node] = min(tree[node << 1], tree[node << 1 | 1]);
		};
		rec(rec, 1, 1, sz);
	}
	int query(int l, int r) {
		auto rec = [&](const auto& self, int node, int node_l, int node_r) -> int {
			push(node);
			if (node_r < l || r < node_l) return 1 << 30;
			if (l <= node_l && node_r <= r) return tree[node];
			int mid = (node_l + node_r) / 2;
			int r1 = self(self, node << 1, node_l, mid);
			int r2 = self(self, node << 1 | 1, mid + 1, node_r);
			return min(r1, r2);
		};
		return rec(rec, 1, 1, sz);
	}
private:
	int sz;
	vector<int> tree;
	vector<int> lazy;
	void push(int i) {
		if (i < sz) {
			lazy[i << 1] += lazy[i];
			lazy[i << 1 | 1] += lazy[i];
		}
		tree[i] += lazy[i];
		lazy[i] = 0;
	}
};

auto sol = [](int n, int m, auto v, auto c) {
	sort(v.begin(), v.end());
	vector buc(0, 0);
	for (int i = 0; i < n; i++) {
		buc.push_back(v[i][0]);
	}
	for (int i = 0; i < m; i++) {
		buc.push_back(c[i]);
	}
	sort(buc.begin(), buc.end());
	buc.erase(unique(buc.begin(), buc.end()), buc.end());
	for (int i = 0; i < n; i++) {
		auto it = lower_bound(buc.begin(), buc.end(), v[i][0]);
		v[i][0] = it - buc.begin() + 1;
	}
	for (int i = 0; i < m; i++) {
		auto it = lower_bound(buc.begin(), buc.end(), c[i]);
		c[i] = it - buc.begin() + 1;
	}
	vector cnt(buc.size() + 1, 0);
	for (int i = 0; i < n; i++) {
		cnt[v[i][0]]++;
	}
	segtree tree(buc.size());
	for (int i = 1; i <= buc.size(); i++) {
		tree.update(1, i, cnt[i]);
	}
	int opt = 0;
	for (int i = 0; i < m; i++) {
		tree.update(1, c[i], -1);
		if (tree.query(1, buc.size()) < 0) break;
		opt = i + 1;
	}
	sort(c.begin(), c.begin() + opt, greater{});
	priority_queue<int> pq;
	i64 acc = 0;
	int pos = n - 1;
	for (int i = 0; i < opt; i++) {
		while (pos >= 0 && v[pos][0] >= c[i]) {
			pq.push(v[pos][1]);
			pos--;
		}
		assert(pq.size());
		acc += pq.top();
		pq.pop();
	}
	return pair(opt, acc);
};

int main() {
	cin.tie(0)->sync_with_stdio(0);
	int n, m; cin >> n >> m;
	vector v(n, array{ 0, 0 });
	vector c(m, 0);
	for (int i = 0; i < n; i++) cin >> v[i][0] >> v[i][1];
	for (int i = 0; i < m; i++) cin >> c[i];
	auto [a, b] = sol(n, m, v, c);
	cout << a << ' ' << b << '\n';
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...