最后一个点过不了,求助!T_T
查看原帖
最后一个点过不了,求助!T_T
398890
TheOnlyMan楼主2021/4/7 17:22

dalao求助,我刷了一页的提交了最后一个点过不了。 T_T

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define p(i) (t[i].first)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int maxn=5e5+5;
const ll inf=1e10+5;
const ll inff=1e16+5;
P t[maxn],que[maxn+1000];
ll dp[maxn];
int head,tail;
inline ll read()
{
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int main()
{
	ll n,d,k;
	cin>>n>>d>>k;
	for(int i=1;i<=n;i++){
		t[i].first=read();
		t[i].second=read();
	} 
	ll l=0,r=inf;
	while(l<=r)
	{
		int mid=(l+r)/2;
		int l1=d+mid,r1=max((int)d-mid,0);//l1指跳跃最大距离,r1指跳跃最小距离
		head=0,tail=0;
		int point=1;//移动指针
		ll kk=0;
		que[++tail].first=0;que[tail].second=0;
		for(int i=1;i<=n;i++){
			dp[i]=-inff;//提前赋值
			if(que[head+1].first+r1>p(i))continue;//如果最前边的点最小距离依然会跳过i点,则i点不用继续算了
			while(point<i&&p(point)+r1<=p(i))
			{//最小距离可以小于i,则可以到达,放进去
//				if(dp[point]==-inf){
//					point++;
//					continue;
//				}
				while(head<tail&&que[tail].second<dp[point])tail--;
				que[++tail].first=p(point);
				que[tail].second=dp[point];
				point++;
			}
			while(head<tail&&que[head+1].first+l1<p(i))head++;//去掉太远的点
			if(head==tail){//头尾相等,则i没有可以继承的点
				dp[i]=-inff;
			} 
			else dp[i]=que[head+1].second+t[i].second;
			kk=max(kk,dp[i]);
			if(kk>=k)break;
		}
//		cout<<'!'<<l<<" "<<r<<" "<<mid<<endl;
//		for(int j=1;j<=n;j++){
//			cout<<dp[j]<<" ";
//		}
//		cout<<kk<<endl;
		if(kk>=k)r=mid-1;
		else l=mid+1; 
	}
	if(l==inf)cout<<-1<<endl;
	else cout<<l<<endl;
	return 0;
}
2021/4/7 17:22
加载中...