【推導】Codeforces Round #478 (Div. 2) D. Ghosts

題意:給你一條直線以及初始時刻這條直線上的一些人的座標,以及他們的速度矢量。讓你對每一個人計算他在過去無限遠到未來無限遠的時間內會與多少人處於同一個點,而後對每一個人的這個值求和。spa

列方程組:兩我的i,j相撞的條件是:blog

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

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

 

化簡得vy(i)-a*vx(i)=vy(j)-a*vx(j),對這個值排序,就能統計了。別忘了減去vx相等的點對貢獻的答案(這種狀況畫個圖出來,顯然永遠不會相撞)。io

#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;
	int sta;
	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;
}
相關文章
相關標籤/搜索