考虑换一个思路,原题说的是两个人的速度同时加w,我们转换成月亮会进行移动。
月亮以每个时刻从中间向两侧移动最多W个单位的速度移动。
我们可以把时间放在纵坐标,把位置放在横坐标,画出如题解中的那样一张图。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
int n;
long long l,w;
long long tr[100005],tl[100005];
int cntr,cntl;
bool check(long long x1,long long x2)
{
double xx=1.0*(x1+x2)/2.0;
double yy=1.0*(x2-x1)/2.0;
if(1.0*yy*w > (-xx) && 1.0*yy*w > (xx))
{
return true;
}
else
return false;
}
int bin(long long x)
{
int l=0,r=cntl-1;
while(l<r)
{
int mid=(l+r)/2;
if(check(x,tl[mid]))
{
r=mid;
}
else
{
l=mid+1;
}
}
if(check(x,tl[l])==false)
{
l++;
}
return min(l,cntl);
}
int main() {
while(~scanf("%d%lld%lld",&n,&l,&w))
{
cntr=cntl=0;
for(int i=0;i<n;i++)
{
long long id,f;
scanf("%lld%lld",&id,&f);
if(f==1)
{
tr[cntr]=id;
cntr++;
}
else
{
id+=l;
tl[cntl]=id;
cntl++;
}
}
sort(tr,tr+cntr);
sort(tl,tl+cntl);
long long ans=0;
//cout<<tr[0]<<" "<<tl[0]<<endl;
//cout<<check(tr[0],tl[0])<<endl;
for(int i=0;i<cntr;i++)
{
//cout<<bin(tr[i])<<endl;
ans+=(cntl-bin(tr[i]));
//cout<<ans<<endl;
}
printf("%lld\n",ans);
}
return 0;
}