[Derivation] Codeforces Round #478 (Div. 2) D. Ghosts

The meaning of the question: give you a line and the coordinates of some people on the line at the initial moment, and their velocity vectors. Let you count for each person how many people he will be at the same point from infinity in the past to infinity in the future, then sum this value for each person.

Column equations: The conditions for two people i, j to collide are:

a*x(i)+b+t*vy(i)=a*xj+b+t*vy(j)

x(i)+t*vx(i)=xj+t*vx(j)

 

Simplify to vy(i)-a*vx(i)=vy(j)-a*vx(j), sort this value, and you can count. Don't forget to subtract the answer for the contribution of point pairs where vx are equal (draw a picture of this situation, which obviously never collide).

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
ll a,b;
typedef pair<ll,ll> Point;
Point c[200005];
int main(){
	ll x,va,vb;
	scanf("%d%I64d%I64d",&n,&a,&b);
	for(int i=1;i<=n;++i){
		scanf("%I64d%I64d%I64d",&x,&va,&vb);
		c[i].first=vb-a*va;
		c [i] .second = va;
	}
	sort(c+1,c+n+1);
	ll ans=0;
	you stay;
	for(int i=1;i<=n;++i){
		if(i==1 || c[i].first!=c[i-1].first){
			sta = i;
		}
		if(i==n || c[i].first!=c[i+1].first){
			ans+=(ll)(i-sta+1)*(ll)(i-sta);
		}
	}
	for(int i=1;i<=n;++i){
		if(i==1 || (c[i].first!=c[i-1].first || c[i].second!=c[i-1].second)){
			sta = i;
		}
		if(i==n || (c[i].first!=c[i+1].first || c[i].second!=c[i+1].second)){
			ans-=(ll)(i-sta+1)*(ll)(i-sta);
		}
	}
	printf("%I64d\n",ans);
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325150345&siteId=291194637