답안 #563081

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
563081 2022-05-16T07:46:30 Z Mazaalai 새 집 (APIO18_new_home) C++17
0 / 100
5000 ms 1048576 KB
#include <bits/stdc++.h>
#define ALL(x) x.begin(),x.end()
#define pb push_back
#define lb lower_bound
// #define int long long
using namespace std;

const int N = 3e5 + 5;
const int M = 1e7 + 5;
struct Query {
	int time, pos, shopType, id, isOpen, isQuery;
};
struct Node {
	multiset <int> vals;
	int lNode, rNode;
	Node() {
		lNode = rNode = -1;
	}
};
int nodes = 1;
Node node[M];
void addSide(Node& tmp) {
	tmp.lNode = nodes++;
	tmp.rNode = nodes++;
}
void update(int l, int r, int L, int R, int val, bool isAdd, int head) { //log^MlogK
	// cout << '\t' << L << ' ' << R << ' ' << val << ' ' << (isAdd ? "+" : "-") << '\n';
	if (max(l, L) > min(r, R)) return;
	if (L <= l && r <= R) {
		if (isAdd) {
			node[head].vals.insert(val);
		} else {
			node[head].vals.erase(node[head].vals.lb(val));
		}
		return;
	}
	int mid = (l+r) / 2;
	if (node[head].lNode == -1) addSide(node[head]);
	update(l, mid, L, R, val, isAdd, node[head].lNode);
	update(mid+1, r, L, R, val, isAdd, node[head].rNode);
}
int queryAns(int l, int r, int pos, int head) { // logN
	if (head < 0) return 0;
	int res = 0;
	if (node[head].vals.size() > 0) res = max(res, abs(pos - *node[head].vals.begin()));
	if (node[head].vals.size() > 1) res = max(res, abs(pos - *node[head].vals.rbegin()));
	int mid = (l+r) / 2;
	if (pos <= mid) res = max(res, queryAns(l, mid, pos, node[head].lNode));
	else res = max(res, queryAns(mid+1, r, pos, node[head].rNode));
	return res;
}
multiset <int> pos[N];
int shopSz;
int segL = 0, segR = 1e8;
void updateQuery(Query& query) { // log^MlogK
	multiset <int>& curSet = pos[query.shopType];
	// cout << (query.isOpen ? "ADD" : "REM") << ' ' << query.pos << ' ' << query.shopType << ' ' << query.time << '\n';
	// cout << curSet.size() << " -> " ;
	if (query.isOpen) {
		curSet.insert(query.pos);
		auto it = curSet.lb(query.pos);
		auto itL = it; itL--;
		auto itR = it; itR++;

		int a = *itL, b = *it, c = *itR;
		int mid = (a + c) / 2;
		int mid1 = (a + b) / 2;
		int mid2 = (b + c) / 2;
		if (a != 0 && c != 1e9) {
			update(segL, segR, a+1, mid, a, 0, 0);
			update(segL, segR, mid+1, c, c, 0, 0);

			update(segL, segR, a+1, mid1, a, 1, 0);
			update(segL, segR, mid1+1, mid2, b, 1, 0);
			update(segL, segR, mid2+1, c, c, 1, 0);
		} else if (a != 0) {
			update(segL, segR, a+1, segR, a, 0, 0);

			update(segL, segR, a+1, mid1, a, 1, 0);
			update(segL, segR, mid1+1, b, b, 1, 0);
			update(segL, segR, b+1, segR, b, 1, 0);
		} else if (c != 1e9) {
			update(segL, segR, segL+1, c, c, 0, 0);

			update(segL, segR, segL+1, b, b, 1, 0);
			update(segL, segR, b+1, mid2, b, 1, 0);
			update(segL, segR, mid2+1, c, c, 1, 0);
		} else {
			update(segL, segR, segL+1, b, b, 1, 0);
			update(segL, segR, b+1, segR, b, 1, 0);
		}
	} else {
		auto it = curSet.lb(query.pos);
		auto itL = it; itL--;
		auto itR = it; itR++;
		int a = *itL, b = *it, c = *itR;
		curSet.erase(it);
		int mid = (a + c) / 2;
		int mid1 = (a + b) / 2;
		int mid2 = (b + c) / 2;
		if (a != 0 && c != 1e9) {
			update(segL, segR, a+1, mid1, a, 0, 0);
			update(segL, segR, mid1+1, mid2, b, 0, 0);
			update(segL, segR, mid2+1, c, c, 0, 0);

			update(segL, segR, a+1, mid, a, 1, 0);
			update(segL, segR, mid+1, c, c, 1, 0);
		} else if (a != 0) {
			update(segL, segR, a+1, mid1, a, 0, 0);
			update(segL, segR, mid1+1, b, b, 0, 0);
			update(segL, segR, b+1, segR, b, 0, 0);

			update(segL, segR, a+1, segR, a, 1, 0);
		} else if (c != 1e9) {
			update(segL, segR, segL+1, b, b, 0, 0);
			update(segL, segR, b+1, mid2, b, 0, 0);
			update(segL, segR, mid2+1, c, c, 0, 0);

			update(segL, segR, segL+1, c, c, 1, 0);
		} else {
			update(segL, segR, segL+1, b, b, 0, 0);
			update(segL, segR, b+1, segR, b, 0, 0);
		}
	}
	// cout << curSet.size() << '\n';
	shopSz += (query.isOpen && curSet.size() == 3);
	shopSz -= (curSet.size() == 2);
}
int ans[N];
int n, q, k;
int getAns(Query& q) { // logN
	// cout << "QUERY: " << q.pos << ' ' << q.id << ' ' << q.time << '\n';
	// cout << shopSz << ' ' << k << '\n';
	if (shopSz < k) return -1;
	return queryAns(segL, segR, q.pos, 0);
}
signed main() {
	// freopen("0.in", "r", stdin);
	// freopen("0.out", "w", stdout);
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n >> k >> q;
	for (int i = 1; i <= k; i++) { // N
		pos[i].insert(0);
		pos[i].insert(1e9);
	}
	vector <Query> queries;
	for (int i = 1; i <= n; i++) { // N
		int x, t, a, b; cin >> x >> t >> a >> b;
		queries.pb({a, x, t, 0, 1, 0});
		queries.pb({b+1, x, t, 0, 0, 0});
	}
	for (int i = 1; i <= q; i++) { // Q
		int x, t; cin >> x >> t;
		queries.pb({t, x, 0, i, 0, 1});
	}
	sort(ALL(queries), [&](Query&a, Query&b) { // (N+Q)log(N+Q)
		return (a.time == b.time ? b.isQuery : a.time < b.time);
	});
	for (auto& query : queries) { // (N+Q)log^MlogK
		if (!query.isQuery) {
			updateQuery(query);
		} else {
			ans[query.id] = getAns(query);
		}
	}
	for (int i = 1; i <= q; i++) 
		cout << ans[i] << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Correct 246 ms 562284 KB Output is correct
2 Execution timed out 5063 ms 562296 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 246 ms 562284 KB Output is correct
2 Execution timed out 5063 ms 562296 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5085 ms 622808 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1110 ms 1048576 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 246 ms 562284 KB Output is correct
2 Execution timed out 5063 ms 562296 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 246 ms 562284 KB Output is correct
2 Execution timed out 5063 ms 562296 KB Time limit exceeded
3 Halted 0 ms 0 KB -