답안 #741425

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
741425 2023-05-14T05:00:02 Z GusterGoose27 송신탑 (IOI22_towers) C++17
14 / 100
1615 ms 134136 KB
#include "towers.h"

#include <bits/stdc++.h>

using namespace std;

typedef array<int, 2> pii;

const int MAXN = 1e5;
const int inf = 1e9;
int height[MAXN];
int n;

class path {
public:
	bool tp; // tp = 0 is >= 2, tp = 1 is single
	pii minmax; // tp = 1
	pii lft; // out in, tp = 0
	pii rt; // out in, tp = 0
	int len; // both
	bool par; // 0 is low, 1 is high, tp = 0
	int d;
	path() {}
	path(int i) {
		d = 0;
		tp = 1;
		minmax = pii{height[i], height[i]};
		len = 1;
		par = 0;
	}
	void reverse() {
		swap(lft, rt);
		par ^= (len&1)^1;
	}
	path(path &l, path &r, int d) : d(d) {
		if (l.tp && r.tp) {
			if (l.minmax[1] >= r.minmax[0]+d) {
				lft = pii{l.minmax[1], r.minmax[0]};
				rt = pii{r.minmax[0], l.minmax[1]};
				len = 2;
				par = 1;
				tp = 0;
				return;
			}
			if (l.minmax[0] <= r.minmax[1]-d) {
				lft = pii{l.minmax[0], r.minmax[1]};
				rt = pii{r.minmax[1], l.minmax[0]};
				len = 2;
				par = 0;
				tp = 0;
				return;
			}
			tp = 1;
			minmax = pii{min(l.minmax[0], r.minmax[0]), max(l.minmax[1], r.minmax[1])};
			len = 1;
			return;
		}
		tp = 0;
		bool rev = 0;
		if (l.tp && !r.tp) {
			rev = 1;
			l.reverse();
			r.reverse();
			swap(l, r);
		}
		if (!l.tp && r.tp) {
			bool rhigh = l.par^(l.len&1)^1; // 0 is mn, 1 is high
			if (rhigh && l.rt[0] >= r.minmax[0]+d) {
				lft = l.lft;
				rt = pii{r.minmax[0], l.rt[0]};
				par = l.par;
				len = l.len+1;
			}
			else if (!rhigh && l.rt[0]+d <= r.minmax[1]) {
				lft = l.lft;
				rt = pii{r.minmax[1], l.rt[0]};
				par = l.par;
				len = l.len+1;
			}
			else if (rhigh && l.rt[0] < r.minmax[1]) {
				rt = pii{r.minmax[1], l.rt[1]};
				par = l.par;
				len = l.len;
				if (len > 2) lft = l.lft;
				else lft = pii{l.rt[1], r.minmax[1]};
			}
			else if (!rhigh && l.rt[0] > r.minmax[0]) {
				rt = pii{r.minmax[0], l.rt[1]};
				par = l.par;
				len = l.len;
				if (len > 2) lft = l.lft;
				else lft = pii{l.rt[1], r.minmax[0]};
			}
			else {
				rt = l.rt;
				lft = l.lft;
				len = l.len;
				par = l.par;
			}
			if (rev) {
				swap(l, r);
				l.reverse();
				r.reverse();
				reverse();
			}
			return;
		}
		par = l.par;
		bool lhigh = l.par^(l.len&1)^1;
		bool rhigh = r.par;
		if (lhigh != rhigh) {
			if ((lhigh && l.rt[0] >= d+r.lft[0]) || (!lhigh && l.rt[0]+d <= r.lft[0])) {
				lft = l.lft;
				rt = r.rt;
				len = l.len+r.len;
				return;
			}
			len = l.len+r.len-2;
			if (l.len > 2) lft = l.lft;
			else lft = pii{l.rt[1], r.lft[1]};
			if (r.len > 2) rt = r.rt;
			else rt = pii{r.lft[1], l.rt[1]};
			return;
		}
		len = l.len+r.len-1;
		if ((lhigh && l.rt[0] > r.lft[0]) || (!lhigh && l.rt[0] < r.lft[0])) {
			lft = l.lft;
			if (r.len > 2) rt = r.rt;
			else rt = pii{r.lft[1], l.rt[0]};
			return;
		}
		if (l.len > 2) lft = l.lft;
		else lft = pii{l.rt[1], r.lft[0]};
		rt = r.rt;
	}
};

class stree {
public:
	int lp, rp;
	stree *l = nullptr;
	stree *r = nullptr;
	vector<path> paths;
	stree(int lv, int rv) {
		lp = lv;
		rp = rv;
		if (lp < rp) {
			int mid = (lp+rp)/2;
			l = new stree(lp, mid);
			r = new stree(mid+1, rp);
			int pos[2]; pos[0] = pos[1] = 0;
			for (int i = rp-lp+1; i > 0; i--) {
				bool cand;
				path cur_path;
				bool mx_reached = 0;
				do {
					if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) {
						mx_reached = 1;
						break;
					}
					cand = (r->get_cost(pos[1]) < l->get_cost(pos[0]));
					pos[cand]++;
					int d = max(r->get_cost(pos[1]), l->get_cost(pos[0]));
					cur_path = path(l->paths[pos[0]], r->paths[pos[1]], d);
				} while (cur_path.len > i); // fix inf condition
				if (!mx_reached) pos[cand]--;
				int mn = max(l->get_cost(pos[0]-1), r->get_cost(pos[1]-1));
				int mx = min(l->get_cost(pos[0]), r->get_cost(pos[1]));
				while (mx > mn+1) {
					int cur = (mn+mx)/2;
					cur_path = path(l->paths[pos[0]], r->paths[pos[1]], cur);
					if (cur_path.len > i) mn = cur;
					else mx = cur;
				}
				if (mx == min(l->get_cost(pos[0]), r->get_cost(pos[1]))) {
					if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) break;
					pos[cand]++;
				}
				paths.push_back(path(l->paths[pos[0]], r->paths[pos[1]], mx));
				i = paths.back().len;
			}
		}
		else {
			paths.push_back(path(lp));
		}
	}
	int get_cost(int p) {
		if (p == paths.size()-1) return inf;
		return paths[p+1].d;
	}
	path* query(int lv, int rv, int d) {
		if (lp > rv || rp < lv) return nullptr;
		if (lp >= lv && rp <= rv) {
			int mn = 0;
			int mx = paths.size();
			// cerr << mn << ' ' << mx << endl;
			while (mx > mn+1) {
				int cur = (mn+mx)/2;
				if (paths[cur].d <= d) mn = cur;
				else mx = cur;
			}
			return &paths[mn];
		}
		path *lq = l->query(lv, rv, d);
		path *rq = r->query(lv, rv, d);
		if (lq == nullptr) return rq;
		if (rq == nullptr) return lq;
		return new path(*lq, *rq, d);
	}
};

stree *tree;

void init(int nn, vector<int> hn) {
	n = nn;
	for (int i = 0; i < n; i++) height[i] = hn[i];
	tree = new stree(0, n-1);
}

int max_towers(int l, int r, int d) {
	path *p = tree->query(l, r, d);
	return (p->len+1-p->par)/2;
}

Compilation message

towers.cpp: In constructor 'stree::stree(int, int)':
towers.cpp:157:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<path>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  157 |      if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) {
      |          ~~~~~~~^~~~~~~~~~~~~~~~~~~~
towers.cpp:157:48: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<path>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  157 |      if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) {
      |                                         ~~~~~~~^~~~~~~~~~~~~~~~~~~~
towers.cpp:176:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<path>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  176 |      if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) break;
      |          ~~~~~~~^~~~~~~~~~~~~~~~~~~~
towers.cpp:176:48: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<path>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  176 |      if (pos[0] == l->paths.size()-1 && pos[1] == r->paths.size()-1) break;
      |                                         ~~~~~~~^~~~~~~~~~~~~~~~~~~~
towers.cpp: In member function 'int stree::get_cost(int)':
towers.cpp:188:9: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<path>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  188 |   if (p == paths.size()-1) return inf;
      |       ~~^~~~~~~~~~~~~~~~~
towers.cpp: In constructor 'stree::stree(int, int)':
towers.cpp:177:14: warning: 'cand' may be used uninitialized in this function [-Wmaybe-uninitialized]
  177 |      pos[cand]++;
      |      ~~~~~~~~^
# 결과 실행 시간 메모리 Grader output
1 Correct 663 ms 47772 KB Output is correct
2 Correct 1390 ms 97184 KB Output is correct
3 Correct 1420 ms 97000 KB Output is correct
4 Correct 1425 ms 97200 KB Output is correct
5 Incorrect 1386 ms 96968 KB 37163rd lines differ - on the 1st token, expected: '1', found: '0'
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 464 KB Output is correct
2 Correct 6 ms 1232 KB Output is correct
3 Correct 5 ms 1232 KB Output is correct
4 Correct 6 ms 1380 KB Output is correct
5 Correct 6 ms 1408 KB Output is correct
6 Correct 6 ms 1488 KB Output is correct
7 Correct 7 ms 1488 KB Output is correct
8 Incorrect 3 ms 848 KB 1st lines differ - on the 1st token, expected: '1', found: '-1'
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 464 KB Output is correct
2 Correct 6 ms 1232 KB Output is correct
3 Correct 5 ms 1232 KB Output is correct
4 Correct 6 ms 1380 KB Output is correct
5 Correct 6 ms 1408 KB Output is correct
6 Correct 6 ms 1488 KB Output is correct
7 Correct 7 ms 1488 KB Output is correct
8 Incorrect 3 ms 848 KB 1st lines differ - on the 1st token, expected: '1', found: '-1'
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1267 ms 109324 KB Output is correct
2 Correct 1610 ms 124936 KB Output is correct
3 Correct 1544 ms 124944 KB Output is correct
4 Correct 1511 ms 133980 KB Output is correct
5 Correct 1596 ms 134012 KB Output is correct
6 Correct 1588 ms 134136 KB Output is correct
7 Correct 1615 ms 133996 KB Output is correct
8 Correct 1296 ms 97096 KB Output is correct
9 Correct 1264 ms 97116 KB Output is correct
10 Correct 1359 ms 97180 KB Output is correct
11 Correct 1427 ms 97208 KB Output is correct
12 Correct 1208 ms 97148 KB Output is correct
13 Correct 1280 ms 97064 KB Output is correct
14 Correct 1 ms 208 KB Output is correct
15 Correct 3 ms 848 KB Output is correct
16 Correct 3 ms 848 KB Output is correct
17 Correct 267 ms 63432 KB Output is correct
18 Correct 328 ms 71996 KB Output is correct
19 Correct 312 ms 72064 KB Output is correct
20 Correct 106 ms 33216 KB Output is correct
21 Correct 102 ms 33132 KB Output is correct
22 Correct 267 ms 63468 KB Output is correct
23 Correct 329 ms 71900 KB Output is correct
24 Correct 318 ms 71980 KB Output is correct
25 Correct 104 ms 33172 KB Output is correct
26 Correct 102 ms 33188 KB Output is correct
27 Correct 6 ms 1232 KB Output is correct
28 Correct 6 ms 1488 KB Output is correct
29 Correct 7 ms 1488 KB Output is correct
30 Correct 3 ms 916 KB Output is correct
31 Correct 3 ms 848 KB Output is correct
32 Correct 5 ms 1232 KB Output is correct
33 Correct 6 ms 1468 KB Output is correct
34 Correct 6 ms 1488 KB Output is correct
35 Correct 3 ms 852 KB Output is correct
36 Correct 3 ms 848 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 314 ms 14272 KB Output is correct
2 Correct 1123 ms 63540 KB Output is correct
3 Incorrect 1210 ms 63572 KB 47543rd lines differ - on the 1st token, expected: '1', found: '0'
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 464 KB Output is correct
2 Correct 6 ms 1232 KB Output is correct
3 Correct 5 ms 1232 KB Output is correct
4 Correct 6 ms 1380 KB Output is correct
5 Correct 6 ms 1408 KB Output is correct
6 Correct 6 ms 1488 KB Output is correct
7 Correct 7 ms 1488 KB Output is correct
8 Incorrect 3 ms 848 KB 1st lines differ - on the 1st token, expected: '1', found: '-1'
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 663 ms 47772 KB Output is correct
2 Correct 1390 ms 97184 KB Output is correct
3 Correct 1420 ms 97000 KB Output is correct
4 Correct 1425 ms 97200 KB Output is correct
5 Incorrect 1386 ms 96968 KB 37163rd lines differ - on the 1st token, expected: '1', found: '0'
6 Halted 0 ms 0 KB -