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;
}

 

posted @ 2017-08-20 15:44  ichneumon  阅读(187)  评论(0编辑  收藏  举报