[BZOJ3190][JLOI2013][单调栈]赛车

版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87866928

BZOJ3190

建出每个赛车的x-t图像,然后就变成那个水平可见直线了
用单调栈维护答案

Code:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int res=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
	while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
	return res*f;
}
const int N=1e4+5;
struct node{
	int v,x,num;
	double k;
}p[N];
int n,s[N],cnt,pt[N];
inline bool cmp(node a,node b) {if(a.v==b.v) return a.x<b.x;return a.v<b.v;}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) p[i].x=read();
	for(int i=1;i<=n;i++) p[i].v=read(),p[i].num=i;
	sort(p+1,p+n+1,cmp);
	for(int i=1;i<=n;i++){
		while(cnt){
			if(p[i].x>p[s[cnt]].x) --cnt;
			else if(1.0*p[s[cnt]].x-p[i].x<p[s[cnt]].k*(p[i].v-p[s[cnt]].v)) --cnt;
			else break;
		}
		if(cnt && p[i].v>p[s[cnt]].v)  p[i].k=(double)(p[s[cnt]].x-p[i].x)/(p[i].v-p[s[cnt]].v);
		s[++cnt]=i;
	}
	for(int i=1;i<=cnt;i++) pt[p[s[i]].num]=1;
	cout<<cnt<<"\n";
	for(int i=1;i<=n;i++) if(pt[i]) cout<<i<<" ";
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43346903/article/details/87866928