#include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define pb push_back typedef long long ll; typedef long double ld; typedef pair pii; typedef vector vi; int main() { cin.tie(0)->sync_with_stdio(0); int n; cin >> n; vector p(n), w(n); ll torque = 0; for(int i = 0; i < n; i++) { cin >> p[i] >> w[i]; torque += p[i]*w[i]; } if(torque > 0) { torque = -torque; for(int i = 0; i < n; i++) p[i] = -p[i]; reverse(all(p)); reverse(all(w)); } struct Group { ll W = 0, N = 0, pos = 0, id = 0; bool operator<(const Group g) const { if(W*g.N == g.W*N) return id < g.id; return W*g.N < g.W*N; } }; set> positions; vector killed(n); priority_queue q; for(int i = 0; i < n; i++) { Group g{w[i], 1, p[i], i}; q.push(g); positions.insert({p[i], g}); } ld ans = 0; ld T = -torque; while(T > 0) { while(killed[q.top().id]) q.pop(); Group curr = q.top(); q.pop(); auto next = positions.upper_bound({curr.pos, curr}); if(next != positions.end()) { ll dist = next->second.pos-curr.pos; if(dist*curr.W < T) { ans += dist*curr.N; T -= dist*curr.W; positions.erase(positions.find({curr.pos, curr})); curr.pos = next->second.pos; curr.W += next->second.W; curr.N += next->second.N; positions.insert({curr.pos, curr}); q.push(curr); killed[next->second.id] = true; positions.erase(next); } else { ans += (ld)T/curr.W*curr.N; T = 0; } } else { ans += (ld)T/curr.W*curr.N; T = 0; } } cout << fixed << setprecision(10) << ans << "\n"; }