题解 P3256 【[JLOI2013]赛车】

· · 题解

单调栈

时间复杂度为O(nlogn),比半平面交常数小。

我才不会说是因为我懒得写半平面交

题解

如果一个人比你小,还比你强,你就肯定打不过他了

考虑这四种情况,就可以愉快地使用单调栈解题了。

把所有的车按v从小到大排序,v相同的按k从小到大排序。

然后每次加入一个车,再将栈中不可能拿第一的车出栈,最后该车入栈。

算完输出一下栈里车的编号就好啦qwq~

代码

#include<bits/stdc++.h>
using namespace std;
int stk[10010],top,n;
struct data{
    int k,v,id;
}a[10010];
bool cmp(data x,data y){
    if(x.v==y.v) return x.k<y.k;
    return x.v<y.v;
}
bool cmp1(int x,int y){
    return a[x].id<a[y].id;
}
double tim(data a,data b){//计算追及时间
    if(a.v==b.v) return 2e9;//防止除0 虽然似乎没有这样的数据
    return double(a.k-b.k)/(b.v-a.v);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) a[i].id=i;
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i].k);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i].v);
    sort(a+1,a+n+1,cmp);
    stk[++top]=1;
    for(int i=2;i<=n;i++){
        while(top&&((a[i].k>a[stk[top]].k)||(top>1&&tim(a[stk[top]],a[i])<tim(a[stk[top-1]],a[stk[top]]))/*||(a[i].v==a[stk[top]].v&&a[i].k>a[stk[top]].k)*/)) top--;//注释部分然并卵
        stk[++top]=i;
    }
    printf("%d\n",top);
    sort(stk+1,stk+top+1,cmp1);
    for(int i=1;i<=top;i++)
    printf("%d ",a[stk[i]].id);
}