QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#723822 | #3035. Ghost | Markadiusz# | WA | 986ms | 4104kb | C++23 | 5.8kb | 2024-11-08 00:58:03 | 2024-11-08 00:58:05 |
Judging History
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
}
}
Details
Tip: Click on the bar to expand more detailed information
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