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;
}