Submission #1048901

# Submission time Handle Problem Language Result Execution time Memory
1048901 2024-08-08T10:45:25 Z flappybird Sweeping (JOI20_sweeping) C++17
22 / 100
3965 ms 489324 KB
//#define LOCAL
#include <bits/stdc++.h>
#include <cassert>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
#define MAX 2010101
#define MAXQ 101010
#define INF 1'000'000'100
#define bb ' '
#define ln '\n'
#define Ln '\n'
#define MOD 1000000007
#define TC 1
#ifdef LOCAL
#define DEBUG(a) cout<<a
#define TEST true
#else
#define DEBUG(...) 1234
#define TEST false
#endif

int N, M, Q;

//points
int X[MAX];
int Y[MAX];
int S[MAX];
vector<int> es[MAX];
//queries
int T[MAX];
int L[MAX];
pii ans[MAX];
vector<int> qv[MAX];

struct node {
	int val;
	int key;
	int p, n;
	int lnk;
	node(int k = 0, int v = 0, int p = 0, int n = 0) :p(p), n(n) {
		val = v;
		key = k;
		lnk = 0;
	}
};

vector<node> MEM;

void disc(int n) {
	if (MEM[n].p) MEM[MEM[n].p].n = MEM[n].n;
	if (MEM[n].n) MEM[MEM[n].n].p = MEM[n].p;
	MEM[n].p = MEM[n].n = 0;
}

int make_node(int k, int v, int p = 0, int n = 0) {
	int s = MEM.size();
	MEM.push_back(node(k, v, p, n));
	return s;
}

struct Dat {
	int sv[2] = { 0, 0 }; //linked list
	int ev[2] = { 0, 0 };
	int cap[2] = { 0, 0 }; //cap from down
	int N;
	void init(vector<int> K, vector<vector<int>> X) {
		vector<pii> ord;
		N = K.size();
		int i;
		for (i = 0; i < N; i++) ord.emplace_back(i, 0);

		sort(ord.begin(), ord.end(), [&](pii i, pii j) {return X[0][i.first] < X[0][j.first]; });
		int pv = 0;
		for (auto& v : ord) {
			int nn = make_node(K[v.first], X[0][v.first], pv);
			if (!sv[0]) sv[0] = nn;
			ev[0] = nn;
			v.second = nn;
			if (pv) MEM[pv].n = nn;
			pv = nn;
		}

		sort(ord.begin(), ord.end(), [&](pii i, pii j) {return X[1][i.first] < X[1][j.first]; });
		pv = 0;
		for (auto& v : ord) {
			int nn = make_node(K[v.first], X[1][v.first], pv);
			if (!sv[1]) sv[1] = nn;
			ev[1] = nn;
			if (pv) MEM[pv].n = nn;
			MEM[nn].lnk = v.second;
			MEM[v.second].lnk = nn;
			pv = nn;
		}
	}

	int& begin(int c) { return sv[c]; }
	int& rbegin(int c) { return ev[c]; }
	node& front(int c) { return MEM[sv[c]]; }
	node& back(int c) { return MEM[ev[c]]; }
};

vector<Dat> lists;
int flag; // flag for divide function

int divide(Dat& D, int c, int L) {
	int op = c ^ 1;
	int n = D.N;
	if (max(D.cap[c], D.front(c).val) >= L) {
		flag = 0;
		return -1;
	}
	if (max(D.cap[c], D.back(c).val) < L) {
		flag = 1;
		return -1;
	}
	int i;
	int chk = 0;
	int rem = 0; // remove
	int s, e;
	s = D.begin(c);
	e = D.rbegin(c);
	for (i = 0; i < n; i++) {
		if (max(D.cap[c], MEM[s].val) >= L) {
			chk = 0;
			rem = i;
			break;
		}
		if (max(D.cap[c], MEM[e].val) < L) {
			chk = 1;
			rem = i;
			break;
		}
		s = MEM[s].n;
		e = MEM[e].p;
	}
	Dat nd;
	nd.cap[0] = D.cap[0];
	nd.cap[1] = D.cap[1];
	s = D.begin(c);
	e = D.rbegin(c);
	nd.N = rem;
	if (chk) { //remove from back
		e = D.rbegin(c);
		vector<int> rems;
		for (i = 0; i < rem; i++) {
			int opn = MEM[e].lnk;
			assert(opn);
			assert(e);
			if (opn == D.begin(op)) D.begin(op) = MEM[opn].n;
			if (opn == D.rbegin(op)) D.rbegin(op) = MEM[opn].p;
			disc(opn);
			rems.push_back(opn);
			e = MEM[e].p;
		}
		int ns = MEM[e].n; // [list 1(original)] ... e / ns ... [list 2(new)]
		MEM[e].n = 0;
		MEM[ns].p = 0;

		// D.sv[op], D.ev[op] is correct

		sort(rems.begin(), rems.end());
		for (i = 1; i < rem; i++) {
			MEM[rems[i - 1]].n = rems[i];
			MEM[rems[i]].p = rems[i - 1];
			assert(MEM[rems[i - 1]].val <= MEM[rems[i]].val);
		}

		nd.sv[c] = ns;
		nd.sv[op] = rems[0];
		nd.ev[c] = D.ev[c];
		nd.ev[op] = rems.back();

		D.ev[c] = e;
		flag = 0;
	}
	else { // remove from front
		s = D.begin(c);
		vector<int> rems;
		for (i = 0; i < rem; i++) {
			int opn = MEM[s].lnk;
			assert(opn);
			assert(e);
			if (opn == D.begin(op)) D.begin(op) = MEM[opn].n;
			if (opn == D.rbegin(op)) D.rbegin(op) = MEM[opn].p;
			disc(opn);
			rems.push_back(opn);
			s = MEM[s].n;
		}
		int ne = MEM[s].p; // [list 1(new)] ... ne / s ... [list 2(original)]
		MEM[s].p = 0;
		MEM[ne].n = 0;

		// D.sv[op], D.ev[op] is correct

		sort(rems.begin(), rems.end());
		for (i = 1; i < rem; i++) {
			MEM[rems[i - 1]].n = rems[i];
			MEM[rems[i]].p = rems[i - 1];
		}

		nd.sv[c] = D.sv[c];
		nd.sv[op] = rems[0];
		nd.ev[c] = ne;
		nd.ev[op] = rems.back();

		D.sv[c] = s;
		flag = 1;
	}
	D.N = n - rem;
	lists.push_back(nd);
	return lists.size() - 1;
}

void solve(int l, int r, vector<int>& v) {
	lists.clear();
	MEM.clear();
	MEM.push_back(node());
	int i;
	int n = v.size();
	vector<int> K(n);
	vector<vector<int>> val(2, vector<int>(K.size()));
	for (i = 0; i < n; i++) {
		K[i] = v[i];
		val[0][i] = X[v[i]];
		val[1][i] = Y[v[i]];
	}
	Dat d;
	d.init(K, val);
	lists.push_back(d);
	set<pii> st; // (left top point of the triangle, index in lists)
	st.emplace(-1, 0);
	for (i = l; i <= r; i++) {
		if (T[i] == 1 || T[i] == 4) continue;
		if (T[i] == 2) {
			int v = N - L[i];
			auto it = st.lower_bound(pii(v, 0));
			it--;
			int pv = it->first;
			int ind1 = it->second;
			st.erase(it);
			int ind2 = divide(lists[ind1], 1, L[i] + 1);

			if (!~ind2) {
				if (flag) lists[ind1].cap[0] = max(lists[ind1].cap[0], v);
				st.emplace(pv, ind1);
				continue;
			}

			if (flag) { //reversed
				st.emplace(pv, ind1);
				st.emplace(v, ind2);
				lists[ind2].cap[0] = max(lists[ind2].cap[0], v);
			}
			else {
				st.emplace(pv, ind2);
				st.emplace(v, ind1);
				lists[ind1].cap[0] = max(lists[ind1].cap[0], v);
			}
		}
		else {
			int v = N - L[i];
			auto it = st.lower_bound(pii(L[i] + 1, 0));
			it--;
			int pv = it->first;
			int ind1 = it->second;
			st.erase(it);
			int ind2 = divide(lists[ind1], 0, L[i] + 1);

			if (!~ind2) {
				if (flag) lists[ind1].cap[1] = max(lists[ind1].cap[1], v);
				st.emplace(pv, ind1);
				continue;
			}

			if (flag) { //reversed
				st.emplace(pv, ind2);
				st.emplace(L[i], ind1);
				lists[ind2].cap[1] = max(lists[ind2].cap[1], v);
			}
			else {
				st.emplace(pv, ind1);
				st.emplace(L[i], ind2);
				lists[ind1].cap[1] = max(lists[ind1].cap[1], v);
			}
		}
	}
	for (auto& d : lists) {
		assert(!MEM[d.sv[0]].p);
		assert(!MEM[d.sv[1]].p);
		assert(!MEM[d.ev[0]].n);
		assert(!MEM[d.ev[1]].n);
		int s = d.sv[0];
		for (i = 0; i < d.N; i++) {
			int v = MEM[s].key;
			X[v] = max(X[v], d.cap[0]);
			Y[v] = max(Y[v], d.cap[1]);
			if (qv[v].size() && qv[v].back() == r) {
				ans[qv[v].back()] = pii(X[v], Y[v]);
				qv[v].pop_back();
			}
			s = MEM[s].n;
		}
	}
}

vector<int> tree[MAX * 4];
vector<tuple<int, int, int>> vt;

void init(int s, int e, int loc = 1) {
	vt.emplace_back(s, e, loc);
	if (s == e) return;
	int m = s + e >> 1;
	init(s, m, loc * 2);
	init(m + 1, e, loc * 2 + 1);
}

void add(int s, int e, int l, int r, int v, int loc = 1) {
	if (e < l || r < s) return;
	if (l <= s && e <= r) {
		tree[loc].push_back(v);
		return;
	}
	int m = s + e >> 1;
	add(s, m, l, r, v, loc * 2);
	add(m + 1, e, l, r, v, loc * 2 + 1);
}

signed main() {
	ios::sync_with_stdio(false), cin.tie(0);
	cin >> N >> M >> Q;
	int i, x;
	for (i = 1; i <= M; i++) {
		cin >> X[i] >> Y[i];
		S[i] = 1;
	}
	init(1, Q);
	for (i = 1; i <= Q; i++) {
		cin >> T[i];
		if (T[i] == 1) {
			cin >> x;
			if (qv[x].empty()) add(1, Q, S[x], i, x);
			else add(1, Q, qv[x].back() + 1, i, x);
			qv[x].push_back(i);
		}
		if (T[i] == 2 || T[i] == 3) cin >> L[i];
		if (T[i] == 4) {
			S[++M] = i;
			cin >> X[M] >> Y[M];
		}
	}
	for (i = 1; i <= M; i++) reverse(qv[i].begin(), qv[i].end());
	sort(vt.begin(), vt.end());
	for (auto& [l, r, v] : vt) if (tree[v].size()) solve(l, r, tree[v]);
	for (i = 1; i <= Q; i++) {
		if (T[i] == 1) {
			cout << ans[i].first << bb << ans[i].second << ln;
			assert(ans[i].first + ans[i].second <= N);
		}		
	}
}

Compilation message

sweeping.cpp: In function 'void init(int, int, int)':
sweeping.cpp:318:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  318 |  int m = s + e >> 1;
      |          ~~^~~
sweeping.cpp: In function 'void add(int, int, int, int, int, int)':
sweeping.cpp:329:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  329 |  int m = s + e >> 1;
      |          ~~^~~
# Verdict Execution time Memory Grader output
1 Correct 65 ms 286480 KB Output is correct
2 Correct 63 ms 286228 KB Output is correct
3 Correct 69 ms 286484 KB Output is correct
4 Correct 72 ms 286560 KB Output is correct
5 Correct 59 ms 286176 KB Output is correct
6 Correct 63 ms 286480 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3234 ms 447344 KB Output is correct
2 Correct 3220 ms 448088 KB Output is correct
3 Correct 3133 ms 448224 KB Output is correct
4 Correct 2122 ms 443844 KB Output is correct
5 Correct 2050 ms 443896 KB Output is correct
6 Correct 2339 ms 445924 KB Output is correct
7 Correct 3227 ms 446992 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2796 ms 440936 KB Output is correct
2 Correct 2475 ms 438712 KB Output is correct
3 Correct 1924 ms 439236 KB Output is correct
4 Correct 1901 ms 439360 KB Output is correct
5 Correct 2353 ms 439240 KB Output is correct
6 Correct 2393 ms 439104 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2796 ms 440936 KB Output is correct
2 Correct 2475 ms 438712 KB Output is correct
3 Correct 1924 ms 439236 KB Output is correct
4 Correct 1901 ms 439360 KB Output is correct
5 Correct 2353 ms 439240 KB Output is correct
6 Correct 2393 ms 439104 KB Output is correct
7 Correct 3236 ms 442248 KB Output is correct
8 Correct 3205 ms 441412 KB Output is correct
9 Correct 3091 ms 442160 KB Output is correct
10 Correct 2048 ms 439328 KB Output is correct
11 Correct 1945 ms 438468 KB Output is correct
12 Correct 2827 ms 434216 KB Output is correct
13 Correct 2520 ms 439048 KB Output is correct
14 Correct 177 ms 321112 KB Output is correct
15 Correct 3965 ms 489324 KB Output is correct
16 Correct 3115 ms 441988 KB Output is correct
17 Incorrect 1892 ms 444856 KB Output isn't correct
18 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 65 ms 286480 KB Output is correct
2 Correct 63 ms 286228 KB Output is correct
3 Correct 69 ms 286484 KB Output is correct
4 Correct 72 ms 286560 KB Output is correct
5 Correct 59 ms 286176 KB Output is correct
6 Correct 63 ms 286480 KB Output is correct
7 Correct 3234 ms 447344 KB Output is correct
8 Correct 3220 ms 448088 KB Output is correct
9 Correct 3133 ms 448224 KB Output is correct
10 Correct 2122 ms 443844 KB Output is correct
11 Correct 2050 ms 443896 KB Output is correct
12 Correct 2339 ms 445924 KB Output is correct
13 Correct 3227 ms 446992 KB Output is correct
14 Correct 2796 ms 440936 KB Output is correct
15 Correct 2475 ms 438712 KB Output is correct
16 Correct 1924 ms 439236 KB Output is correct
17 Correct 1901 ms 439360 KB Output is correct
18 Correct 2353 ms 439240 KB Output is correct
19 Correct 2393 ms 439104 KB Output is correct
20 Correct 3236 ms 442248 KB Output is correct
21 Correct 3205 ms 441412 KB Output is correct
22 Correct 3091 ms 442160 KB Output is correct
23 Correct 2048 ms 439328 KB Output is correct
24 Correct 1945 ms 438468 KB Output is correct
25 Correct 2827 ms 434216 KB Output is correct
26 Correct 2520 ms 439048 KB Output is correct
27 Correct 177 ms 321112 KB Output is correct
28 Correct 3965 ms 489324 KB Output is correct
29 Correct 3115 ms 441988 KB Output is correct
30 Incorrect 1892 ms 444856 KB Output isn't correct
31 Halted 0 ms 0 KB -