hdu6136[模拟+优先队列] 2017多校8
有点麻烦..
/*hdu6136[模拟+优先队列] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long long LL; struct frac { LL p, q; frac(LL P, LL Q) { p = P / __gcd(P, Q); q = Q / __gcd(P, Q); } frac() {p = 0, q = 1;} bool operator < (const frac& a) const { return p * a.q < q * a.p; } bool operator > (const frac& a) const { return p * a.q > q * a.p; } frac operator + (frac a) const { LL d = __gcd(q, a.q); LL P = a.q / d * p + q / d * a.p; return frac(P, q / d * a.q); } }; ostream& operator << (ostream& out, const frac& a) { out << a.p << "/" << a.q ; return out; } struct node { LL v; LL d; int s, pos; node(LL V = 0, LL D = 0, int S = 0): v(V), d(D), s(S) {} } a[200005]; struct Node { int l, r; frac f; Node(int L, int R, frac F): l(L), r(R) , f(F) {} Node() {r = l = 0;} bool operator < (const Node& a) const { return f > a.f; } }; bool cmp(const node& a, const node& b) { return a.d < b.d; } int T, n, dead[200005], nxt[200005], pre[200005]; LL l; frac gettime(node a, node b) { LL dist = b.d - a.d; if (dist < 0) dist = l - (a.d - b.d); if (a.v >= 0 && b.v <= 0) { return frac(dist, a.v - b.v); } if (a.v <= 0 && b.v >= 0) { return frac(l - dist, b.v - a.v); } if (a.v >= 0 && b.v >= 0) { if (b.v > a.v) { return frac(l - dist, b.v - a.v); } else return frac(dist, a.v - b.v); } else if (a.v <= 0 && b.v <= 0) { if (b.v < a.v) { return frac(dist, a.v - b.v); } else return frac(l - dist, b.v - a.v); } return frac(); } void del(int x) { nxt[pre[x]] = nxt[x]; pre[nxt[x]] = pre[x]; } void solve() { //memset(nxt, 0, sizeof(nxt)); //memset(pre, 0, sizeof(pre)); memset(dead, 0, sizeof(dead)); sort(a, a + n, cmp); priority_queue<Node>q; for (int i = 0; i < n; i++) { if (n == 2) { nxt[0] = 1, pre[1] = 0; nxt[1] = 0, pre[0] = 1; q.push(Node(0, 1, gettime(a[0], a[1]))); break; } nxt[i] = (i + 1) % n; pre[(i + 1) % n] = i; q.push(Node(i, (i + 1) % n, gettime(a[i], a[(i + 1) % n]))); } frac ans(0, 1); int deadnum = 0; while (!q.empty()) { Node now = q.top(); q.pop(); if (dead[now.l] || dead[now.r]) continue; // puts(""); //cout << a[now.l].s << " meet " << a[now.r].s << endl; //cout << "dist: " << a[now.l].d << ' ' << a[now.r].d << endl; //cout << "need: " << now.f << endl; if (deadnum == n - 2) { while (!q.empty()) { now = q.top(); q.pop(); if (!dead[now.l] && !dead[now.r]) { break; } } ans = now.f; break; } if (a[now.l].s > a[now.r].s) { del(now.r); dead[now.r]++; deadnum++; //cout << "kill: " << a[now.r].s << endl; //cout << "push: " << a[now.l].d << ' ' << a[nxt[now.l]].d << endl; if (now.l != nxt[now.l]) q.push(Node(now.l, nxt[now.l], gettime(a[now.l], a[nxt[now.l]]))); } else { del(now.l); dead[now.l]++; deadnum++; //cout << "kill: " << a[now.l].s << endl; // cout << "push: " << a[pre[now.r]].d << ' ' << a[now.r].d << endl; if (pre[now.r] != now.r) q.push(Node(pre[now.r], now.r, gettime(a[pre[now.r]], a[now.r]))); } } printf("%lld/%lld\n", ans.p, ans.q); } int main() { scanf("%d", &T); while (T--) { scanf("%d%lld", &n, &l); for (int i = 0; i < n; i++) { a[i].s = i; scanf("%lld", &a[i].d); } for (int i = 0; i < n; i++) { scanf("%lld", &a[i].v); } solve(); } return 0; }