QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#736655 | #2582. 物理实验 | propane | 0 | 1370ms | 8748kb | C++20 | 6.4kb | 2024-11-12 12:15:26 | 2024-11-12 12:15:27 |
Judging History
answer
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<set>
#include<iomanip>
#include<array>
using namespace std;
using LL = long long;
template<typename T>
T sign(T x){
if (x > 0) return 1;
if (x < 0) return -1;
return 0;
}
template<typename T>
T abs(T x){
if (x < 0) x = -x;
return x;
}
template<typename T>
T gcd(T a, T b){
if (b == 0) return a;
return gcd(b, a % b);
}
struct Point{
long double x, y;
Point operator+(const Point &t) const {
return {x + t.x, y + t.y};
}
Point operator-(const Point &t) const {
return {x - t.x, y - t.y};
}
Point operator*(long double t) const {
return {x * t, y * t};
}
Point operator/(long double t) const {
return {x / t, y / t};
}
long double operator*(const Point &t) const {
return x * t.x + y * t.y;
}
long double operator^(const Point &t) const {
return x * t.y - y * t.x;
}
long double len(){
return sqrtl(x * x + y * y);
}
};
struct Fraction{
LL x, y; __int128_t v;
long double val;
// _x * _x / y
Fraction(LL _x, LL _y){
val = _x / sqrtl(_y);
__int128_t t = __int128_t(_x) * _x * sign(_x);
v = t / _y;
x = t % _y;
y = _y;
LL g = abs(gcd(x, y));
x /= g; y /= g;
}
bool operator<(const Fraction &t) const {
if (v != t.v) return v < t.v;
return __int128_t(x) * t.y < __int128_t(y) * t.x;
}
bool operator==(const Fraction &t) const {
return v == t.v and x == t.x and y == t.y;
}
};
long double cur_x;
struct Segment{
Point a, b;
long double k() const {
return (b - a).len() / (b.x - a.x);
}
bool operator<(const Segment& t) const {
long double y1 = a.y + (cur_x - a.x) / (b.x - a.x) * (b.y - a.y);
long double y2 = t.a.y + (cur_x - t.a.x) / (t.b.x - t.a.x) * (t.b.y - t.a.y);
return abs(y1) < abs(y2);
}
};
struct Event{
Fraction t; int id, type;
bool operator<(const Event &a) const {
if (t == a.t) return type < a.type;
return t < a.t;
}
};
int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cout << fixed << setprecision(10);
int T;
cin >> T;
while(T--){
int n;
cin >> n;
vector<array<LL, 4> > p(n);
for(int i = 0; i < n; i++){
for(auto &x : p[i]){
cin >> x;
}
}
LL x1, y1, x2, y2, L;
cin >> x1 >> y1 >> x2 >> y2 >> L;
Point a = {1.0L * x1, 1.0L * y1}, b = {1.0L * x2, 1.0L * y2};
LL dx = x2 - x1, dy = y2 - y1;
LL sqr = dx * dx + dy * dy;
Point v1 = {1.0L * dx, 1.0L * dy};
v1 = v1 / v1.len();
Point v2 = v1;
swap(v2.x, v2.y);
v2.x = -v2.x;
// v = {1.0L * dx, 1.0L * dy};
// v = v / v.len();
// a = {1.0L * x1, 1.0L * y1};
// b = {1.0L * x2, 1.0L * y2};
vector<Segment> seg(n);
vector<Fraction> nums;
vector<Event> event;
nums.reserve(2 * n);
event.reserve(2 * n);
for(int i = 0; i < n; i++){
auto [x3, y3, x4, y4] = p[i];
vector<Fraction> q;
{
LL dot = (x3 - x1) * dx + (y3 - y1) * dy;
q.push_back(Fraction(dot, sqr));
nums.push_back(q.back());
}
{
LL dot = (x4 - x1) * dx + (y4 - y1) * dy;
q.push_back(Fraction(dot, sqr));
nums.push_back(q.back());
}
if (q[1] < q[0]){
swap(q[0], q[1]);
swap(x3, x4);
swap(y3, y4);
}
Point p1 = {1.0L * x3, 1.0L * y3};
Point p2 = {1.0L * x4, 1.0L * y4};
seg[i] = {{p1 * v1, p1 * v2}, {p2 * v1, p2 * v2}};
event.push_back({q[0], i, 1});
event.push_back({q[1], i, 0});
}
sort(nums.begin(), nums.end());
nums.erase(unique(nums.begin(), nums.end()), nums.end());
sort(event.begin(), event.end());
vector<long double> sum(nums.size() - 1);
vector<long double> len(nums.size() - 1);
set<Segment> st[2];
for(int i = 0, j = 0; i + 1 < nums.size(); i++){
len[i] = nums[i + 1].val - nums[i].val;
cur_x = nums[i].val;
while(j < event.size() and (event[j].t == nums[i] and event[j].type == 0)){
auto [_, id, type] = event[j++];
st[seg[id].a.y > 0].erase(seg[id]);
}
while(j < event.size() and (event[j].t == nums[i] and event[j].type == 1)){
auto [_, id, type] = event[j++];
st[seg[id].a.y > 0].insert(seg[id]);
}
for(int k = 0; k < 2; k++){
if (!st[k].empty()){
sum[i] += st[k].begin()->k() * len[i];
}
}
}
long double ans = 0, val = 0;
for(int i = 0, j = 0; i + 1 < nums.size(); i++){
if (i - 1 >= 0){
val -= sum[i - 1];
}
while(j + 1 < nums.size() and nums[j + 1].val - nums[i].val <= L){
val += sum[j++];
}
long double cur = val;
if (nums[j].val - nums[i].val < L and j + 1 < nums.size()){
cur += (L - (nums[j].val - nums[i].val)) / len[j] * sum[j];
}
ans = max(ans, cur);
}
val = 0;
for(int i = nums.size() - 1, j = nums.size() - 1; i >= 1; i--){
if (i < sum.size()){
val -= sum[i];
}
while(j - 1 >= 0 and nums[i].val - nums[j - 1].val <= L){
val += sum[--j];
}
long double cur = val;
if (nums[i].val - nums[j].val < L and j - 1 >= 0){
cur += (L - (nums[i].val - nums[j].val)) / len[j - 1] * sum[j - 1];
}
ans = max(ans, cur);
}
cout << ans << '\n';
}
}
詳細信息
Pretests
Final Tests
Test #1:
score: 0
Wrong Answer
time: 9ms
memory: 4024kb
input:
100 100 7143 -4407 6148 -4332 -3698 1987 -3674 2827 -2240 -6374 -3784 -6054 149 599 327 597 -2580 -4497 -2820 -4347 9219 -1818 6904 502 -5893 1341 -4357 -1890 -3503 -3287 -1087 -1211 -1579 7118 -229 7556 6456 502 1926 -1748 540 6714 -528 6825 1561 8432 -701 8357 422 6998 -41 7462 -1793 3676 1602 517...
output:
627.1837180465 379.3869761313 254.6487535284 17659.9479963997 497.2944674531 336.3539619440 17195.0068017169 817.6373237405 714.2352816021 347.0073814054 1460.9691201712 10187.7133594574 1062.0222738142 331.6878612174 440.7260757894 918.1347482785 453.4856736067 28409.3978378012 14311.0152324594 84....
result:
wrong answer wrong answer, 1st numbers differ - expected: '939.774677', found: '627.183718', error = '0.332623'
Test #2:
score: 0
Wrong Answer
time: 1175ms
memory: 8740kb
input:
100 10000 954303 48690 -14339 924721 464270 12166 -1609 433494 873644 42682 -12246 843861 449837 10414 -1919 418980 537496 14550 -6578 506603 552080 15962 -6594 521226 870138 42252 -12332 840332 57161 -702218 -671596 -43163 38907 -433607 -402515 -34409 445719 9913 -1981 414808 399734 5765 -1530 3686...
output:
23150.0458715745 1431133.1399987752 21928.0886630746 2894.3797744163 14332.0000004859 3538.3767726667 29100.3730066491 21624.6473093922 22441.5237287938 54764.0090929364 19598.7362562615 31668.9568153676 5004.2680565818 38083.6532006107 30109.3965771401 23164.4454521219 31180.8983261767 17134.063509...
result:
wrong answer wrong answer, 1st numbers differ - expected: '23150.536873', found: '23150.045872', error = '0.000021'
Test #3:
score: 0
Wrong Answer
time: 1370ms
memory: 8748kb
input:
100 10000 -636684471 -90006000 664665488 86376811 -263230447 -307903883 362658164 -223073366 -575841687 -121133860 614287459 40176834 -258935135 -268238570 347975250 -185982857 -287828480 -521064727 443096738 -422002609 -315452625 -391084040 435133968 -289354496 -560776752 -215271244 624810954 -5458...
output:
13997710.8309134719 17046552.4418307580 17146142.6570877983 7797486.7614408197 24229340.8276590728 13387746.9424728360 11289299.0096069266 28761125.8250269149 25407741.8280279574 43288108.2237971275 16696606.0022791895 18751581.6085298255 32220762.5128061797 22030848.0532682162 24775684.6155446203 2...
result:
wrong answer wrong answer, 1st numbers differ - expected: '13997587.658382', found: '13997710.830913', error = '0.000009'