Submission #768401

#TimeUsernameProblemLanguageResultExecution timeMemory
768401SanguineChameleonSeats (IOI18_seats)C++17
37 / 100
4054 ms173448 KiB
#include "seats.h"
#include <bits/stdc++.h>
using namespace std;

const int maxN = 1e6 + 20;

struct node {
	int maxR, minR, maxC, minC;

	node(): maxR(0), minR(0), maxC(0), minC(0) {};

	node(int _maxR, int _minR, int _maxC, int _minC): maxR(_maxR), minR(_minR), maxC(_maxC), minC(_minC) {};
};

node merge(node left, node right) {
	return node(max(left.maxR, right.maxR), min(left.minR, right.minR), max(left.maxC, right.maxC), min(left.minC, right.minC));
}

node tree[maxN * 4];
int maxR[maxN];
int minR[maxN];
int maxC[maxN];
int minC[maxN];
int R[maxN];
int C[maxN];
priority_queue<int, vector<int>, greater<int>> posR[maxN];
priority_queue<int, vector<int>, greater<int>> posC[maxN];
int N, H, W;
int cnt;
bool sub3;

void build(int id, int lt, int rt) {
	if (lt == rt) {
		tree[id] = node(R[lt], R[lt], C[lt], C[lt]);
		return;
	}
	int mt = (lt + rt) >> 1;
	build(id << 1, lt, mt);
	build(id << 1 | 1, mt + 1, rt);
	tree[id] = merge(tree[id << 1], tree[id << 1 | 1]);
}

void update(int id, int lt, int rt, int pos) {
	if (lt == rt) {
		tree[id] = node(R[lt], R[lt], C[lt], C[lt]);
		return;
	}
	int mt = (lt + rt) >> 1;
	if (pos <= mt) {
		update(id << 1, lt, mt, pos);
	}
	else {
		update(id << 1 | 1, mt + 1, rt, pos);
	}
	tree[id] = merge(tree[id << 1], tree[id << 1 | 1]);
}

node get(int id, int lt, int rt, int pos) {
	if (lt == rt) {
		return tree[id];
	}
	int mt = (lt + rt) >> 1;
	if (pos <= mt) {
		return get(id << 1, lt, mt, pos);
	}
	else {
		return merge(tree[id << 1], get(id << 1 | 1, mt + 1, rt, pos));
	}
};

void give_initial_chart(int _H, int _W, vector<int> _R, vector<int> _C) {
	H = _H;
	W = _W;
	N = H * W;
	sub3 = (H <= 1000 && W <= 1000);
	for (int i = 1; i <= N; i++) {
		R[i] = _R[i - 1] + 1;
		C[i] = _C[i - 1] + 1;
	}
	if (sub3) {
		for (int i = 1; i <= N; i++) {
			posR[R[i]].push(i);
			posC[C[i]].push(i);
		}
		build(1, 1, N);
	}
	else {
		minR[0] = H + 1;
		minC[0] = W + 1;
		for (int i = 1; i <= N; i++) {
			maxR[i] = max(R[i], maxR[i - 1]);
			minR[i] = min(R[i], minR[i - 1]);
			maxC[i] = max(C[i], maxC[i - 1]);
			minC[i] = min(C[i], minC[i - 1]);
			if ((maxR[i] - minR[i] + 1) * (maxC[i] - minC[i] + 1) == i) {
				cnt++;
			}
		}
	}
}

int swap_seats(int a, int b) {
	if (sub3) {
		a++;
		b++;
		swap(R[a], R[b]);
		swap(C[a], C[b]);
		update(1, 1, N, a);
		update(1, 1, N, b);
		posR[R[a]].push(a);
		posC[C[a]].push(a);
		posR[R[b]].push(b);
		posC[C[b]].push(b);
		priority_queue<int> cands;
		for (int i = 1; i <= H; i++) {
			int pos = -1;
			while (pos == -1 && !posR[i].empty()) {
				if (R[posR[i].top()] == i) {
					pos = posR[i].top();
					break;
				}
				else {
					posR[i].pop();
				}
			}
			if (pos > 1) {
				cands.push(pos - 1);
			}
		}
		for (int i = 1; i <= W; i++) {
			int pos = -1;
			while (pos == -1 && !posC[i].empty()) {
				if (C[posC[i].top()] == i) {
					pos = posC[i].top();
					break;
				}
				else {
					posC[i].pop();
				}
			}
			if (pos > 1) {
				cands.push(pos - 1);
			}
		}
		int pos = -1;
		cnt = 1;
		while (!cands.empty()) {
			if (cands.top() != pos) {
				pos = cands.top();
				node bounds = get(1, 1, N, pos);
				if ((bounds.maxR - bounds.minR + 1) * (bounds.maxC - bounds.minC + 1) == pos) {
					cnt++;
				}
			}
			cands.pop();
		}
		return cnt;
	}
	else {
		a++;
		b++;
		if (a > b) {
			swap(a, b);
		}
		for (int i = a; i <= b; i++) {
			if ((maxR[i] - minR[i] + 1) * (maxC[i] - minC[i] + 1) == i) {
				cnt--;
			}
		}
		swap(R[a], R[b]);
		swap(C[a], C[b]);
		for (int i = a; i <= b; i++) {
			maxR[i] = max(R[i], maxR[i - 1]);
			minR[i] = min(R[i], minR[i - 1]);
			maxC[i] = max(C[i], maxC[i - 1]);
			minC[i] = min(C[i], minC[i - 1]);
			if ((maxR[i] - minR[i] + 1) * (maxC[i] - minC[i] + 1) == i) {
				cnt++;
			}
		}
		return cnt;
	}
}
#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...