Submission #748564

# Submission time Handle Problem Language Result Execution time Memory
748564 2023-05-26T13:21:32 Z alex_2008 Radio Towers (IOI22_towers) C++17
0 / 100
1304 ms 186020 KB
#include "towers.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <set>
#include <algorithm>
using namespace std;
int ind = -1;
bool ch = true;
vector <int> h;
const int N = 100100, M = 20;
int mx[N][M], Left[N], Right[N], pref[N], LS[N], RS[N];
int mxleft[N][M], mnright[N][M];
struct Node {
	int val;
	int left;
	int right;
	Node* ls;
	Node* rs;
};
Node* roots[N];
int tree[4 * N], maxim[4 * N], minim[4 * N];
int minnumber = 2e9, answer_for_another_tree = 0;
void build_another_tree(int v, int tl, int tr) {
	if (tl == tr) {
		maxim[v] = h[tl];
		minim[v] = h[tl];
		tree[v] = 0;
	}
	else {
		int tm = (tl + tr) / 2;
		build_another_tree(2 * v, tl, tm);
		build_another_tree(2 * v + 1, tm + 1, tr);
		maxim[v] = max({ maxim[2 * v], maxim[2 * v + 1] });
		minim[v] = min({ minim[2 * v], minim[2 * v + 1] });
		tree[v] = max({ tree[2 * v], tree[2 * v + 1], maxim[2 * v + 1] - minim[2 * v] });
	}
}
void query_in_another_tree(int v, int tl, int tr, int l, int r) {
	if (tr < l || tl > r) return;
	if (tl >= l && tr <= r) {
		answer_for_another_tree = max(answer_for_another_tree, tree[v]);
		answer_for_another_tree = max(answer_for_another_tree, maxim[v] - minnumber);
		minnumber = min(minnumber, minim[v]);
		return;
	}
	int tm = (tl + tr) / 2;
	query_in_another_tree(2 * v, tl, tm, l, r);
	query_in_another_tree(2 * v + 1, tm + 1, tr, l, r);
}
void build_tree(Node* v) {
	if (v->left == v->right) {
		v->val = 1;
		return;
	}
	else {
		int tm = (v->left + v->right) / 2;
		Node* ls = new Node{ 0, v->left, tm, nullptr, nullptr };
		Node* rs = new Node{ 0, tm + 1, v->right, nullptr, nullptr };
		build_tree(ls);
		build_tree(rs);
		v->ls = ls;
		v->rs = rs;
		v->val = ls->val + rs->val;
	}
}
void update(Node* old, Node* neww, int pos) {
	*neww = *old;
	if (neww->left > pos || neww->right < pos) return;
	if (neww->left == neww->right) {
		neww->val = 0;
		return;
	}
	int tm = (neww->left + neww->right) / 2;
	Node* ls = new Node{ 0, neww->left, tm, nullptr, nullptr };
	Node* rs = new Node{ 0, tm + 1, neww->right, nullptr, nullptr };
	update(old->ls, ls, pos);
	update(old->rs, rs, pos);
	neww->ls = ls;
	neww->rs = rs;
	neww->val = ls->val + rs->val;
}
int ql = 2e9, qr = -1;
void query1(Node* v, int l) {
	if (v->val == 0) return;
	if (v->right < l) return;
	if (v->left >= l) {
		if (v->val) {
			while (v->left != v->right) {
				if (v->ls->val > 0) {
					v = v->ls;
				}
				else {
					v = v->rs;
				}
			}
			ql = min(ql, v->left);
		}
		return;
	}
	query1(v->ls, l);
	query1(v->rs, l);
}
void query2(Node* v, int r) {
	if (v->val == 0) return;
	if (v->left > r) return;
	if (v->right <= r) {
		if (v->val) {
			while (v->left != v->right) {
				if (v->rs->val > 0) {
					v = v->rs;
				}
				else v = v->ls;
			}
			qr = max(qr, v->left);
		}
		return;
	}
	query2(v->ls, r);
	query2(v->rs, r);
}
int query3(Node* v, int l, int r) {
	if (v->left > r || v->right < l) return 0;
	if (v->left >= l && v->right <= r) return v->val;
	return query3(v->ls, l, r) +
		query3(v->rs, l, r);
}
vector <pair<int, int>> esim;
vector <int> indexes;
bool check = true;
int findmaxinrange(int L, int R) {
	if (L > R) return 0;
	int u = log2(R - L + 1);
	return max(mx[L][u], mx[R - (1 << u) + 1][u]);
}
void init(int n, vector<int> a) {
	ch = true;
	ind = -1;
	h = a;
	pref[0] = 0;
	for (int i = 0; i < n - 1; ++i)
	{
		if (a[i] > a[i + 1]) {
			if (ind == -1) ind = i;
		}
		else {
			if (ind != -1) ch = false;
		}
	}
	LS[0] = -1;
	RS[n - 1] = -1;
	for (int i = 1; i < n; i++) {
		int v = i - 1;
		while (v != -1 && a[i] < a[v]) {
			v = LS[v];
		}
		LS[i] = v;
	}
	for (int i = n - 2; i >= 0; i--) {
		int v = i + 1;
		while (v != -1 && a[i] < a[v]) {
			v = RS[v];
		}
		RS[i] = v;
	}
	for (int i = 1; i < n - 1; i++) {
		pref[i] = pref[i - 1];
		if (a[i] < a[i + 1] && a[i] < a[i - 1]) pref[i]++;
	}
	for (int i = 0; i < n; i++) {
		mx[i][0] = a[i];
	}
	for (int j = 1; j < 20; j++) {
		for (int i = n - 1; i >= 0; i--) {
			mx[i][j] = max(mx[i][j - 1], mx[min(n - 1, i + (1 << (j - 1)))][j - 1]);
		}
	}
	for (int i = 0; i < n; i++) {
		int hmn = 2e9;
		if (LS[i] != -1) {
			hmn = min(hmn, findmaxinrange(LS[i] + 1, i - 1));
		}
		if (RS[i] != -1) {
			hmn = min(hmn, findmaxinrange(i + 1, RS[i] - 1));
		}
		int u = hmn - a[i];
		esim.push_back({ u, i });
	}
	sort(esim.begin(), esim.end());
	roots[0] = new Node{ 0, 0, n - 1, nullptr, nullptr };
	build_tree(roots[0]);
	for (int i = 1; i < n; i++) {
		roots[i] = new Node{ 0, 0, n - 1, nullptr, nullptr };
		update(roots[i - 1], roots[i], esim[i - 1].second);
	}
	build_another_tree(1, 0, n - 1);
}
int querynumber = 0;
int max_towers(int L, int R, int D) {
	int n = (int)h.size();
	int left = 0, right = n - 1, answ = -1;
	while (left <= right) {
		int mid = (left + right) / 2;
		if (esim[mid].first >= D) {
			answ = mid;
			right = mid - 1;
		}
		else left = mid + 1;
	}
	if (answ == -1) return 1;
	int ans = query3(roots[answ], L, R);
	ql = 2e9;
	qr = -1;
	query1(roots[answ], L);
	query2(roots[answ], R);
	minnumber = 2e9;
	answer_for_another_tree = 0;
	if (ql != 2e9) {
		int left = L, right = ql - 1, r__ = -1;
		while (left <= right) {
			int mid = (left + right) / 2;
			if (findmaxinrange(mid, ql) - h[ql] >= D) {
				r__ = mid;
				left = mid + 1;
			}
			else right = mid - 1;
		}
		if (r__ != -1 && r__ >= L) {
			query_in_another_tree(1, 0, n - 1, L, r__);
			if (answer_for_another_tree >= D) ++ans;
		}
	}
	minnumber = 2e9;
	answer_for_another_tree = 0;
	if (qr != -1) {
		int left = qr + 1, right = R, r__ = -1;
		while (left <= right) {
			int mid = (left + right) / 2;
			if (findmaxinrange(qr, mid) - h[qr] >= D) {
				r__ = mid;
				right = mid - 1;
			}
			else left = mid + 1;
		}
		if (r__ != -1) {
			query_in_another_tree(1, 0, n - 1, r__, R);
			if (answer_for_another_tree >= D) ++ans;
		}
	}
	if (ans == 0) ++ans;
	return ans;
	//query left = INF, query right = -1
/*
7 1
10 20 60 40 50 30 70
1 5 10
*/
/*auto it = lower_bound(indexes.begin(), indexes.end(), L);
int ans = upper_bound(indexes.begin(), indexes.end(), R) - lower_bound(indexes.begin(), indexes.end(), L);
if (it != indexes.end()) {
	int q = Left[*it];
	if (L < q) {
		if (findmininrange(L, q - 1, 2) < *it) {
			++ans;
		}
	}
}
it = upper_bound(indexes.begin(), indexes.end(), R);
if (it != indexes.begin()) {
	--it;
	int q = Right[*it];
	if (q < R) {
		if (findmininrange(q + 1, R, 1) > *it) {
			++ans;
		}
	}
}
if (ans == 0) ++ans;*/
	return ans;
}
# Verdict Execution time Memory Grader output
1 Incorrect 717 ms 106336 KB 1st lines differ - on the 1st token, expected: '1', found: '2'
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 720 KB Output is correct
2 Incorrect 4 ms 2916 KB 1st lines differ - on the 1st token, expected: '292', found: '293'
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 720 KB Output is correct
2 Incorrect 4 ms 2916 KB 1st lines differ - on the 1st token, expected: '292', found: '293'
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1233 ms 184664 KB 1st lines differ - on the 1st token, expected: '11903', found: '11902'
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 307 ms 40076 KB Output is correct
2 Correct 1304 ms 185940 KB Output is correct
3 Incorrect 1266 ms 186020 KB 5231st lines differ - on the 1st token, expected: '29', found: '30'
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 720 KB Output is correct
2 Incorrect 4 ms 2916 KB 1st lines differ - on the 1st token, expected: '292', found: '293'
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 717 ms 106336 KB 1st lines differ - on the 1st token, expected: '1', found: '2'
2 Halted 0 ms 0 KB -