专题链接:https://codeforces.com/group/5yyKg9gx7m/contest/269717/problem/D
思路
先用二分法求出T,再对每只牛按所在的位置排序,记入这时每只牛的排名,然后预测出T时间后每只牛的位置,再次进行排序,将一个方向的所有牛的排名差加起来即为答案
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<cstring>
#include<climits>
#include<vector>
#include<queue>
#include<stack>
#define lowbit(i) ((i)&(-(i)))
#define ll long long
using namespace std;
int N, L,sum,T;
int ans;
int ra[50001];
struct note
{
int w;
double x;//坐标
int d; // 速度
int id;
}cow[50001];
bool cam(note a, note b)
{ return a.x < b.x;}
bool check(int mid)
{
int l=0, r=0;
for (int i = 1; i <= N; i++)
{
int tem = cow[i].x +(int)cow[i].d * mid;
if (tem <= 0) l++;
if (tem >= L)r++;
}
int tot=0;
for (int i = 1; i <= l; i++)
tot += cow[i].w;
for (int i = 1; i <= r; i++)
tot += cow[N - i + 1].w;
if (tot*2 >= sum)
return 1;
return 0;
}
int main()
{
cin >> N >> L;
for (int i = 1; i <= N; i++)
{
int w, x, d;
scanf("%d%d%d", &w, &x, &d);
sum += w;
cow[i].w = w;
cow[i].x = x;
cow[i].d = d;
cow[i].id = i;
}
sort(cow + 1, cow + N + 1, cam);
for (int i = 1; i <= N; i++)
{
ra[cow[i].id] = i;
}
int l = 0, r = 1e9;
int mid;
while (r >= l)//求T
{
mid = (r + l) / 2;
if (check(mid))
{
r = mid - 1;
T = mid;
}
else
l = mid + 1;
}
for (int i = 1; i <= N; i++)
{
if (cow[i].d == 1)
cow[i].x += T+0.1;//各位加0.1是为了避免两只牛因并列而漏数的情况
else
cow[i].x -= T;
}
sort(cow + 1, cow + N + 1, cam);
for (int i = 1; i <= N; i++)
if (cow[i].d == 1)
ans +=abs(ra[cow[i].id]-i);
//printf("ans1==%d ans2==%d\n", ans1, ans2);
printf("%d\n", ans);
return 0;
}