Submission #243040

#TimeUsernameProblemLanguageResultExecution timeMemory
243040atoizNew Home (APIO18_new_home)C++14
100 / 100
3760 ms233148 KiB
/*input
2 1 3
1 1 1 4
1 1 2 6
1 3
1 5
1 7

1 1 1
100000000 1 1 1
1 1

4 2 4
3 1 1 10
9 2 2 4
7 2 5 7 
4 1 8 10
5 3
5 6
5 9
1 10




*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <map>
#include <set>

using namespace std;

const int MAXN = 300007, INF = 900 * 1000 * 1000;

void minimize(int &x, int y) { x = (x < y ? x : y); }
void maximize(int &x, int y) { x = (x > y ? x : y); }

struct SegmentTree
{
	int N;
	vector<int> A;

	void init(int _N)
	{
		for (N = _N + 5; N & (N - 1); ++N);
		A.assign(N * 2, INF);
	}

	void modify(int l, int r, int x)
	{
		for (l += N, r += N; l < r; l >>= 1, r >>= 1) {
			if (l & 1) minimize(A[l++], x);
			if (r & 1) minimize(A[--r], x);
		}
	}

	int get(int i)
	{
		int ans = INF;
		for (i += N; i >= 1; i >>= 1) minimize(ans, A[i]);
		return ans;
	}
} it;

int N, Q, K;
struct Store { int x, t, a, b, i; } S[MAXN];
struct Border 
{ 
	int x, t, a, b, v; 
	Border(int _x = 0, int _t = 0, int _a = 0, int _b = 0, int _v = 0): x(_x), t(_t), a(_a), b(_b), v(_v) {}
};
struct Query
{
	int x, y, i;
};

int last[MAXN * 2], ans[MAXN];
map<int, vector<int>> events;
set<pair<int, int>> curSet[MAXN];
vector<Border> rightBorder, leftBorder;
vector<Query> queries;
vector<int> times;

void addBorder(pair<int, int> p, pair<int, int> q, int t, int curTime)
{
	int i = p.second, j = q.second;
	int x = (p.first + q.first) >> 1;
	// cout << "add " << i << ' ' << j << ' ' << x << ' ' << curTime << endl;
	int a = last[i], b = curTime;
	last[i] = curTime;
	// if (t == 2) cout << "border " << x << ' ' << a << ' ' << b << ' ' << t << ": " << p.first << ' ' << q.first << " - " << i << endl;
	if (i > N && j > N) {
		leftBorder.emplace_back(-INF, t, a, b, INF);
		rightBorder.emplace_back(INF, t, a, b, -INF);
	} else {
		leftBorder.emplace_back(x, t, a, b, q.first);
		rightBorder.emplace_back(x, t, a, b, p.first);
	}
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> N >> K >> Q;
	for (int i = 1; i <= N; ++i) {
		cin >> S[i].x >> S[i].t >> S[i].a >> S[i].b; S[i].i = i;
		// cout << i << ": " << S[i].a << ' ' << S[i].b << endl;
		S[i].x *= 2, ++S[i].b;
		events[S[i].a].push_back(i);
		events[S[i].b].push_back(i);
	}

	for (int t = 1; t <= K; ++t) {
		last[N + t] = 0;
		curSet[t].emplace(-INF, N + t);
		curSet[t].emplace(INF, N + t);
	}

	for (auto ts : events) {
		int curTime = ts.first;
		for (int i : ts.second) {
			int t = S[i].t, x = S[i].x;	
			if (S[i].a == curTime) {
				last[i] = curTime;
				curSet[t].emplace(x, i);
				auto j = curSet[t].find(make_pair(x, i));
				addBorder(*prev(j), *next(j), t, curTime);
			} else {
				auto j = curSet[t].find(make_pair(x, i));
				addBorder(*prev(j), *j, t, curTime);
				addBorder(*j, *next(j), t, curTime);
				curSet[t].erase(j);
			}
		}
	}

	for (int t = 1; t <= K; ++t) addBorder(*curSet[t].begin(), *curSet[t].rbegin(), t, INF);

	times.push_back(-INF);
	for (auto &b : leftBorder) times.push_back(b.a), times.push_back(b.b);
	for (auto &b : rightBorder) times.push_back(b.a), times.push_back(b.b);
	sort(times.begin(), times.end());
	times.erase(unique(times.begin(), times.end()), times.end());
	// for (int x : times) cout << x << ' '; cout << endl;
	for (auto &b : leftBorder) {
		b.a = (int) (upper_bound(times.begin(), times.end(), b.a) - times.begin());
		b.b = (int) (upper_bound(times.begin(), times.end(), b.b) - times.begin());
	}
	for (auto &b : rightBorder) {
		b.a = (int) (upper_bound(times.begin(), times.end(), b.a) - times.begin());
		b.b = (int) (upper_bound(times.begin(), times.end(), b.b) - times.begin());
	}

	queries.resize(Q);
	for (int i = 0; i < Q; ++i) {
		cin >> queries[i].x >> queries[i].y;
		queries[i].x *= 2;
		queries[i].y = (int) (upper_bound(times.begin(), times.end(), queries[i].y) - times.begin());
		queries[i].i = i;
	}
	sort(leftBorder.begin(), leftBorder.end(), [&](Border a, Border b) { return a.x < b.x; });
	sort(rightBorder.begin(), rightBorder.end(), [&](Border a, Border b) { return a.x > b.x; });
	for (int i = 0; i < Q; ++i) ans[i] = -1;

	sort(queries.begin(), queries.end(), [&](Query p, Query q) { return p.x > q.x; });
	it.init((int) times.size());
	auto b = rightBorder.begin();
	for (auto &q : queries) {
		for (; b != rightBorder.end() && b->x >= q.x; ++b) {
			// cout << "r " << b->x << ": " << b->a << ' ' << b->b << ' ' << b->v << endl;
			it.modify(b->a, b->b, b->v);
		}
		int x = it.get(q.y);
		// cout << "g " << q.y << ": " << q.x << " - " << x << ", " << q.i << endl;
		if (x != INF) maximize(ans[q.i], q.x - x);
	}
	// cout << "-" << endl;

	reverse(queries.begin(), queries.end());
	it.init((int) times.size());
	b = leftBorder.begin();
	for (auto &q : queries) {
		for (; b != leftBorder.end() && b->x <= q.x; ++b) {
			// cout << "l " << b->x << ": " << b->a << ' ' << b->b << ' ' << b->v << endl;
			it.modify(b->a, b->b, -b->v);
		}
		int x = -it.get(q.y);
		// cout << "g " << q.y << ": " << q.x << " - " << x << ", " << q.i << endl;
		if (x != -INF) maximize(ans[q.i], x - q.x);
	}
	// cout << "-" << endl;

	for (int i = 0; i < Q; ++i) {
		if (ans[i] >= 200 * 1000 * 1000) ans[i] = -2;
		cout << (ans[i] / 2) << '\n';
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...