代码 1 和代码 2 的区别仅在代码 1 中第 19 行的语句
while(head<=tail && x[q[head]]+d+g < x[i]) head++;
放在了代码 1 中第 15 行的 while 循坏中,而代码 2 中放在循环外,但代码 1 WA,代码 2 AC。
#include<bits/stdc++.h>
using namespace std;
const long long N=500005;
long long n,d,k,ans;
long long x[N],s[N];
long long f[N],q[N],head=1,tail,now,maxv;
bool calc(long long g)
{
memset(f,128,sizeof(f));
maxv=0;
f[0]=0;
head=1; tail=0; now=0;
for(long long i=1; i<=n; i++)
{
while(now<=n && x[now]+max(1ll,d-g) <= x[i])
{
while(head<=tail && f[now]>=f[q[tail]]) tail--;
q[++tail]=now;
while(head<=tail && x[q[head]]+d+g < x[i]) head++;
now++;
}
if(head<=tail) f[i]=f[q[head]]+s[i],maxv=max(maxv,f[i]);
}
if(maxv<k) return false;
return true;
}
void solve()
{
long long l=0,r=x[n],mid;
while(l<=r)
{
mid=l+r>>1;
if(calc(mid))
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
}
int main()
{
scanf("%lld%lld%lld",&n,&d,&k);
long long jud=0;
for(long long i=1; i<=n; i++) scanf("%lld%lld",&x[i],&s[i]),jud+=max(0ll,s[i]);
if(jud<k)
{
printf("-1");
return 0;
}
solve();
printf("%lld",ans);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const long long N=500005;
long long n,d,k,ans;
long long x[N],s[N];
long long f[N],q[N],head=1,tail,now,maxv;
bool calc(long long g)
{
memset(f,128,sizeof(f));
maxv=0;
f[0]=0;
head=1; tail=0; now=0;
for(long long i=1; i<=n; i++)
{
while(now<=n && x[now]+max(1ll,d-g) <= x[i])
{
while(head<=tail && f[now]>=f[q[tail]]) tail--;
q[++tail]=now;
now++;
}
while(head<=tail && x[q[head]]+d+g < x[i]) head++;
if(head<=tail) f[i]=f[q[head]]+s[i],maxv=max(maxv,f[i]);
}
if(maxv<k) return false;
return true;
}
void solve()
{
long long l=0,r=x[n],mid;
while(l<=r)
{
mid=l+r>>1;
if(calc(mid))
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
}
int main()
{
scanf("%lld%lld%lld",&n,&d,&k);
long long jud=0;
for(long long i=1; i<=n; i++) scanf("%lld%lld",&x[i],&s[i]),jud+=max(0ll,s[i]);
if(jud<k)
{
printf("-1");
return 0;
}
solve();
printf("%lld",ans);
return 0;
}