HDU - 6136 Death Podracing
题意
给定长l的环上的n个人,每个人有给不相同的速度和位置,相遇时编号大的存活,问最后留存一个人时的时间
做法
直接用堆来模拟即可
#include <bits/stdc++.h> using namespace std; typedef long long LL; struct Frac { LL fz, fm; Frac() {} template<class T> Frac(T a):fz(a), fm(1) {} template<class T> Frac(T a, T b):fz(a), fm(b) {} Frac norm() { if (fz < 0 && fm < 0) fz = -fz, fm = -fm; return Frac(fz, fm); } Frac operator + (Frac rhs) { return Frac(fz * rhs.fm + fm * rhs.fz, rhs.fm * fm).norm(); } Frac operator - (Frac rhs) { return Frac(fz * rhs.fm - fm * rhs.fz, rhs.fm * fm).norm(); } Frac operator * (Frac rhs) { return Frac(fz * rhs.fz, fm * rhs.fm).norm(); } Frac operator / (Frac rhs) { return Frac(fz * rhs.fm, fm * rhs.fz).norm(); } }; Frac operator - (int a, Frac b) { return Frac(a) - b; } Frac operator + (int a, Frac b) { return Frac(a) + b; } Frac operator / (int a, Frac b) { return Frac(a) / b; } bool operator < (const Frac&a, const Frac&b) { return a.fz * b.fm < a.fm * b.fz; } bool operator > (const Frac&a, const Frac&b) { return a.fz * b.fm > a.fm * b.fz; } bool operator <= (const Frac&a, const Frac&b) { return a.fz * b.fm <= a.fm * b.fz; } ostream& operator << (ostream&os, Frac a) { LL d = __gcd(a.fz, a.fm); return os << (a.fz / d) << '/' << (a.fm / d); } istream& operator >> (istream&is, Frac&a) { LL d; is >> d; a = d; return is; } const int N = 1e5 + 100; int n, l; struct Ant { int id; Frac p, v; bool operator < (const Ant&rhs) const { return p < rhs.p; } } a[N]; struct Node { Node *suc, *pre; Ant* a; } nd[N]; struct Info { Frac tim; Node *a, *b; Info() {} Info(Frac tim, Node*a, Node*b):tim(tim), a(a), b(b) {} bool operator < (const Info&rhs) const { return tim > rhs.tim; } }; priority_queue<Info> pq; bool del[N]; Frac getTime(Ant a, Ant b) { Frac v = b.v - a.v; Frac d = b.p - a.p; if (d < 0) d = d + l; if (v > 0) { d = l - d; } else d = 0 - d; return d / v; } int main() { #ifdef lol freopen("d.in", "r", stdin); freopen("d.out", "w", stdout); #endif ios_base::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while (T--) { cin >> n >> l; for (int i = 1; i <= n; ++i) cin >> a[i].p; for (int i = 1; i <= n; ++i) { cin >> a[i].v; a[i].id = i; } sort(a + 1, a + n + 1); while (!pq.empty()) pq.pop(); memset(del, 0, sizeof del); for (int i = 2; i <= n; ++i) { nd[i].pre = &nd[i - 1]; nd[i - 1].suc = &nd[i]; nd[i].a = &a[i]; pq.push(Info(getTime(a[i - 1], a[i]), &nd[i - 1], &nd[i])); } nd[1].pre = &nd[n]; nd[n].suc = &nd[1]; nd[1].a = &a[1]; pq.push(Info(getTime(a[n], a[1]), &nd[n], &nd[1])); Frac ans = 0; while (!pq.empty()) { Info u = pq.top(); pq.pop(); if (del[u.a->a->id] || del[u.b->a->id]) continue; if (u.a->a->id == u.b->a->id) break; ans = max(ans, u.tim); if (u.a->a->id > u.b->a->id) { del[u.b->a->id] = true; u.b->suc->pre = u.a; u.a->suc = u.b->suc; pq.push(Info(getTime(*u.a->a, *u.a->suc->a), u.a, u.a->suc)); } else { del[u.a->a->id] = true; u.a->pre->suc = u.b; u.b->pre = u.a->pre; pq.push(Info(getTime(*u.b->pre->a, *u.b->a), u.b->pre, u.b)); } } cout << ans << endl; } return 0; }