QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#723822#3035. GhostMarkadiusz#WA 986ms4104kbC++235.8kb2024-11-08 00:58:032024-11-08 00:58:05

Judging History

你现在查看的是最新测评结果

  • [2024-11-08 00:58:05]
  • 评测
  • 测评结果:WA
  • 用时:986ms
  • 内存:4104kb
  • [2024-11-08 00:58:03]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
#define FOR(i,l,r) for(int i=(l);i<=(r);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) int(x.size())
#ifdef DEBUG
auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";}
#define debug(X...) cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X)
#else
#define debug(...) {}
#endif

using D = double;

struct Tree {
	vector<D> tree;
	int sz = 1;
	Tree(int n) {
		while (sz < n)
			sz *= 2;
		tree.resize(2 * sz);
	}
	void add(int pos, D val) {
		pos += sz;
		while (pos) {
			tree[pos] = max(tree[pos], val);
			pos /= 2;
		}
	}
	D que(int w, int a, int b, int l, int r) {
		if (a > r or b < l) {
			return 0;
		}
		if (a >= l and b <= r){
			return tree[w];
		}
		const int mid = (a + b) / 2;
		return max(
				que(w * 2, a, mid, l, r),
				que(w * 2 + 1, mid + 1, b, l, r)
				);
	}
	D query(int l, int r) {
		return que(1, 0, sz - 1, l, r);
	}
};

const D eps = 1e-9;
bool equal(D a, D b) { return abs(a - b) < eps; }
bool my_equal(D a, D b) { return abs(a - b) < eps; }
bool leq(D a, D b) { return equal(a, b) or a <= b; }
bool le(D a, D b) {
	bool ret = not equal(a, b) and a < b;
	debug(a, b, ret);
	return ret;
}

struct Line {
	mutable D a, b, p;
	D eval(D x) const { return D(a) * x + D(b); }
	bool operator<(const Line & o) const { return a < o.a; }
	bool operator<(D x) const { return p < x; }
};
struct LineContainerMax : multiset<Line, less<>> {
	/*
	const LL inf = LLONG_MAX;
	LL div(LL a, LL b) { return a / b - ((a ^ b) < 0 && a % b); }
	*/
	const D inf = 1 / .0;
	D div(D a, D b) { return a / b; }
	bool intersect(iterator x, iterator y) {
		if (y == end()) { x->p = inf; return false; }
		if (equal(x->a, y->a)) x->p = x->b > y->b ? inf : -inf;
		else x->p = div(y->b - x->b, x->a - y->a);
		return x->p >= y->p;
	}
	void add(D a, D b) {
		debug("max", a, b);
		auto z = insert({a, b, 0}), y = z++, x = y;
		while (intersect(y, z)) z = erase(z);
		if (x != begin() && intersect(--x, y))
			intersect(x, erase(y));
		while((y = x) != begin() && (--x)->p >= y->p)
			intersect(x, erase(y));
	}
	D query(D x) {
		assert(!empty());
		return lower_bound(x)->eval(x);
	}
};
struct LineContainerMin : multiset<Line, less<>> {
	/*
	const LL inf = LLONG_MAX;
	LL div(LL a, LL b) { return a / b - ((a ^ b) < 0 && a % b); }
	*/
	const D inf = 1 / .0;
	D div(D a, D b) { return a / b; }
	bool intersect(iterator x, iterator y) {
		if (y == end()) { x->p = inf; return false; }
		if (equal(x->a, y->a)) x->p = x->b > y->b ? inf : -inf;
		else x->p = div(y->b - x->b, x->a - y->a);
		return x->p >= y->p;
	}
	void add(D a, D b) {
		debug("min", a, b);
		a = -a;
		b = -b;
		auto z = insert({a, b, 0}), y = z++, x = y;
		while (intersect(y, z)) z = erase(z);
		if (x != begin() && intersect(--x, y))
			intersect(x, erase(y));
		while((y = x) != begin() && (--x)->p >= y->p)
			intersect(x, erase(y));
	}
	D query(D x) {
		assert(!empty());
		return -lower_bound(x)->eval(x);
	}
};

int main() {
	cin.tie(0)->sync_with_stdio(0);

	cout << setprecision(10) << fixed;

	int t;
	cin >> t;
	REP(tt, t) {
		int n;
		cin >> n;

		vector<LineContainerMin> Min(2);
		vector<LineContainerMax> Max(2);
		REP(i, n) {
			vector<int> bot(2), top(2), speed(2);
			cin >> bot[0] >> bot[1];
			cin >> top[0] >> top[1];
			cin >> speed[0] >> speed[1];
			debug(i, bot, top, speed);

			REP(j, 2) {
				Min[j].add(speed[j], top[j]);
				Max[j].add(speed[j], bot[j]);
			}
		}

		auto eval = [&](D x) {
			auto one = max<D>(0, Min[0].query(x) - Max[0].query(x));
			auto two = max<D>(0, Min[1].query(x) - Max[1].query(x));
			auto ret = one * two;
			debug(x, ret, one, two);
			debug(Min[0].query(x), Max[0].query(x));
			debug(Min[1].query(x), Max[1].query(x));
			return ret;
		};

		vector<D> events;

		int q;
		cin >> q;

		vector<D> left(q), right(q);

		auto process = [&](auto& h) {
			vector<Line> v(h.begin(), h.end());
			REP(i, ssize(v) - 1) {
				auto [a, b, _] = v[i];
				auto [c, d, _2] = v[i + 1];
				debug(i, a, b, c, d);
				const D x = D(d - b) / D(a - c);
				if (equal(a, c))
					continue;
				debug(x);
				events.emplace_back(x);
			}
		};

		REP(i, 2) {
			process(Min[i]);
			process(Max[i]);
		}

		sort(events.begin(), events.end(), le);

		debug(events);

		events.erase(unique(events.begin(), events.end(), my_equal), events.end());
		debug(events);


		{
			const int ITERS = 100;
			vector<D> new_events = events;
			REP(i, ssize(events) - 1) {
				D bb = events[i], ee = events[i + 1];
				REP(j, ITERS) {
					if (equal(bb, ee))
						break;
					D left = (2 * bb + ee) / 3;
					D right = (bb + 2 * ee) / 3;
					D val_left = eval(left);
					D val_right = eval(right);
					if (val_left < val_right) {
						bb = left;
					}
					else {
						ee = right;
					}
				}
				new_events.emplace_back((bb + ee) / 2);
			}
			swap(new_events, events);
		}


		REP(i, q) {
			cin >> left[i] >> right[i];
			events.emplace_back(left[i]);
			events.emplace_back(right[i]);
		}
		debug(left, right, events);

		sort(events.begin(), events.end(), le);

		debug(events);

		events.erase(unique(events.begin(), events.end(), my_equal), events.end());
		debug(events);

		auto get_id = [&](D x) {
			auto it = lower_bound(events.begin(), events.end(), x, le);
			assert(it != events.end());
			//assert(*it == x);
			return int(it - events.begin());
		};

		Tree tree(ssize(events));
		REP(i, ssize(events)) {
			tree.add(i, eval(events[i]));
		}

		debug(events);

		REP(i, q) {
			const int l = get_id(left[i]);
			const int r = get_id(right[i]);
			auto answer = tree.query(l, r);
			debug(i, l, r, answer);
#ifdef LOCAL
			const int s = 1e3;
			FOR(j, 0, s) {
				D p = (j * left[i] + (s - j) * right[i]) / s;
				assert(leq(eval(p), answer));
			}
#else
			cout << answer << '\n';
#endif
		}
#ifdef LOCAL
		cout << "OK\n";
#endif
	}
}

详细

Test #1:

score: 0
Wrong Answer
time: 986ms
memory: 4104kb

input:

4000
2
-5 -5 3 1 1 -5
-3 -4 -1 2 -2 1
169
4.5924 9.7635
4.9674 5.3219
8.2418 9.6649
6.5743 8.6108
5.3524 6.4199
2.1932 4.3636
1.7115 6.6926
0.5762 4.0628
5.0348 7.5678
6.2170 6.3381
7.1571 8.0276
1.7285 2.3730
0.3843 2.9644
0.0038 0.3971
3.8448 9.7040
4.0458 9.4878
1.6425 7.9132
8.9195 9.4455
4.2563...

output:

0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
3.0856000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
5.3884000000
9.9544000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0...

result:

wrong answer Error is to high: expected 0.025000, but got 0.024779