Run
Since members of Wuhan University ACM Team are lack of exercise, they plan to participate in a ten-thousand-people Marathon. It is common that the athletes run very fast at first but slow down later on. Start from this moment, we can assume that everyone is moving forward in a constant speed. ACMers love algorithms, so they want to know not only the result but also who may be in the leading position. Now we know all athletes' position and speed at a specific moment. The problem is, starting from this moment, how many athletes may be the leader. Please notice that there's no leader if two or more athletes are at the leading position at the same time. No two athletes may have the same speed.
Input
The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. The first line of each test case consists of an integer N, indicating the number of athletes. Each of the following N lines consists of two integers: p, v, indicating an athlete's position and speed.
Technical Specification
1. T ≤ 20
2. 0 < N ≤ 50000
3. 0 < p, v ≤ 2000,000,000
4. An athlete's position is the distant between him/her and the start line.
5. The Marathon is so long that you can assume there's no finishline.
Output
For each test case, output the number of possible leaders on a separate line.
Sample Input
1 3 1 1 2 3 3 2
Sample Output
2
题解
这题可以明显做一下半平面交
但是有一个做法比较机智,避免了大码量的计算几何,所以要讲一下
我们做半平面交用的是s-t图
有一个明显的性质:一个人被超过了之后就不会再反超了
我们尝试直接用v-p图,把一个人当作一个点
那么两点之间的斜率就是(vx-vy)/(px-py),恰好是相遇时间的倒数1/t (太巧妙了)(但应该是老套路了吧。。。)
考虑按p,v分别为第一关键字和第二关键字来进行从大到小排序
很明显,当一个人的位置靠后,速度又比较慢的话,就永远出不了头 (好现实啊。。。)
还有一些人,他们有能力超过目前跑在最前面的人,但是它们的速度不够快,在出头之前被别人超过了,也不能统计(好惨…)
这两种情况我们可以通过一个类似斜率优化的单调栈来处理
然后就A了
代码:(不知道为什么,这道题被放在了随机化作业里。。。哦,原来是题型随机的作业,还有道网络流也被放了进来。。。)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50005
#define LL long long
struct node{
int x,v;
bool operator <(const node &t)const{return x>t.x||(x==t.x&&v>t.v);}
}a[N];
int stk[N],top;
bool check(node x,node y,node z)
{
//(y.x-x.x,y.y-x.y)X(z.x-x.x,z.y-x.y);
if(1ll*(y.x-x.x)*(z.v-x.v)<=1ll*(y.v-x.v)*(z.x-x.x))
return 1;
return 0;
}
int main()
{
int T,n,i,mx;
scanf("%d",&T);
while(T--){
top=0;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].v);
sort(a+1,a+n+1);
mx=a[1].v;stk[++top]=1;
for(i=2;i<=n;i++){
if(a[i].v<mx)continue;
mx=a[i].v;
while(top>1&&check(a[stk[top-1]],a[stk[top]],a[i]))
top--;
stk[++top]=i;
}
printf("%d\n",top);
}
}