Two barns are located at positions?00?and?LL?(1≤L≤109)(1≤L≤109)?on a one-dimensional number line. There are also?NN?cows?(1≤N≤5?104)(1≤N≤5?104)?at distinct locations on this number line (think of the barns and cows effectively as points). Each cow?ii?is initially located at some position?xixi?and moving in a positive or negative direction at a speed of one unit per second, represented by an integer?didi?that is either?11?or??1?1. Each cow also has a weight?wiwi?in the range?[1,103][1,103]. All cows always move at a constant velocity until one of the following events occur:
Let?TT?be the earliest point in time when the sum of the weights of the cows that have stopped moving (due to reaching one of the barns) is at least half of the sum of the weights of all cows. Please determine the total number of meetings between pairs of cows during the range of time?0…T0…T?(including at time?TT).
The first line contains two space-separated integers?NN?and?LL.The next?NN?lines each contain three space-separated integers?wiwi,?xixi, and?di.di.?All locations?xixi?are distinct and satisfy?0<xi<L.0<xi<L.
Print a single line containing the answer.
3 5 1 1 1 2 2 -1 3 3 -1
2
The cows in this example move as follows:
Exactly two meetings occurred.
Problem credits: Benjamin Qi
<h3>USACO 2019 December Contest, Silver Problem 2. Meetings 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Benjamin Qi)
Note: This problem is quite tricky for silver!
First, sort all the cows by?xx-coordinate. For partial credit, we can simulate each collision that the cows make in?O(N),O(N),?for a worst-case runtime of?O(N3).O(N3).
To make solving the problem in?O(NlogN)O(Nlog?N)?more manageable, let's split it into two independent parts.
Part 1:?Determining?T.T.
Consider the multiset of all times when the cows reach the barns. If the cows did not actually switch velocities,
Nevertheless, this multiset remains the same regardless of whether cows switch velocities or not.
Let?zz?be the number of cows with?di=?1.di=?1.?Then exactly?zz?cows reach the left barn, so these must be precisely the?zz?leftmost cows. Thus, we can just take all of the?xixi?for the cows with initial?di=?1di=?1?and set these equal to the finishing times of the?zz?leftmost cows. Similarly, we can just take all of the?L?xiL?xi?for cows with initial?di=1di=1?and set these equal to the finishing times of the?N?zN?z?rightmost cows. After this, we can sort all the finishing times again and maintain the current total weight in order to determine?T.T.
Part 2:?Determining the number of meetings.
Now we can ignore the weight condition and assume that cows do not switch velocities after meeting; essentially, they will pass through each other. This will not affect the answer. Then two cows with?xi<xjxi<xj?will meet if?di=1,dj=?1,xi+2T≥xj.di=1,dj=?1,xi+2T≥xj.?The number of such pairs can be computed by iterating from left to right and maintaining a queue that consists of those cows with?di=1di=1?that you are currently considering as meeting candidates.
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<pair<int,int>> vpi; #define FOR(i,a,b) for (int i = (a); i < (b); ++i) #define F0R(i,a) FOR(i,0,a) #define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i) #define R0F(i,a) ROF(i,0,a) #define trav(a,x) for (auto& a: x) #define pb push_back #define rsz resize #define sz(x) int(x.size()) #define all(x) begin(x), end(x) #define f first #define s second void setIO(string name) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } int N,L; vi w,x,d; void init() { setIO("meetings"); cin >> N >> L; w.rsz(N), x.rsz(N), d.rsz(N); F0R(i,N) cin >> w[i] >> x[i] >> d[i]; vi inds(N); iota(all(inds),0); sort(all(inds),[](int a, int b) { return x[a] < x[b]; }); vi W,X,D; trav(t,inds) { W.pb(w[t]); X.pb(x[t]); D.pb(d[t]); } swap(w,W), swap(x,X), swap(d,D); } int getTime() { vi lef, rig; F0R(i,N) { if (d[i] == -1) lef.pb(x[i]); else rig.pb(x[i]); } vpi v; F0R(i,sz(lef)) v.pb({lef[i],w[i]}); F0R(i,sz(rig)) v.pb({L-rig[i],w[sz(lef)+i]}); sort(all(v)); int tot = 0; trav(t,v) tot += t.s; trav(t,v) { tot -= 2*t.s; if (tot <= 0) return t.f; } } int main() { init(); int t = getTime(); queue<int> rig; int ans = 0; F0R(i,N) { if (d[i] == -1) { while (sz(rig) && rig.front()+2*t < x[i]) rig.pop(); ans += sz(rig); } else rig.push(x[i]); } cout << ans << "\n"; }
For some more problems in the same spirit see
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1