解题思路:
如果两个点在某一个时刻相遇过那么就有一个时刻k使得
x1+k*Vx1 = x2 + k*Vx2 ①
y1+k*Vy1 = y2 + k*Vy2 ②
又有y = ax+b,代入②中得 ax1+k*Vy1 = ax2+k*Vy2 ③
a*① - ③ 得
a*Vx1 - Vy1 = a*Vx2 - Vy2
所以满足上面条件的两个点肯定可以相遇,另外需要注意的是当Vx1=Vx2和Vy1=Vy2时是不能算的因为虽然满足上面式子,但是他们的轨迹是平行的
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 2e5 + 10;
int n,m;
ll a,b,angle[mx];
multiset <pair<ll,ll>> st;
int main()
{
scanf("%d%I64d%I64d",&n,&a,&b);
ll x,y,vx,vy;
for(int i=1;i<=n;i++){
scanf("%I64d%I64d%I64d",&x,&vx,&vy);
angle[i] = a*vx - vy;
st.insert(make_pair(vx,vy));
}
sort(angle+1,angle+1+n);
ll ans = 0;
int pos = 1;
while(pos<=n){
int R = upper_bound(angle+1,angle+1+n,angle[pos]) - angle;
ans += 1ll*(R-pos)*(R-pos-1);
pos = R;
}
while(st.begin()!=st.end())
{
auto it = st.begin();
ans -= 1ll*st.count(*it)*(st.count(*it)-1);
st.erase(*it);
}
printf("%I64d\n",ans);
return 0;
}