题目:https://www.luogu.org/problemnew/show/P3957
二分答案以后可以dp求最优解,转移就是一个滑动窗口,所以用单调队列。
上午想好开 long long ,下午来了又忘了。到手的1A飞了。
但其实觉得很奇怪,因为一个 <k (<1e9)的数加一个s(<=1e5)怎么会爆 int ?
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=5e5+5; int n,D,lm,x[N],c[N],ans=-1,q[N],he,tl; ll dp[N]; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return fx?ret:-ret; } bool solve(int l,int r) { memset(dp,-2,sizeof dp); dp[0]=0; he=1;tl=0;q[0]=-1; for(int i=1;i<=n;i++) { while(x[i]-x[q[tl]+1]>=l) { int d=q[tl]+1; while(he<=tl&&dp[d]>dp[q[tl]])tl--; q[++tl]=d; } while(he<=tl&&x[i]-x[q[he]]>r)he++; if(he>tl)continue; dp[i]=dp[q[he]]+c[i]; if(dp[i]>=lm)return true; } return false; } int main() { n=rdn(); D=rdn(); lm=rdn(); for(int i=1;i<=n;i++)x[i]=rdn(),c[i]=rdn(); int l=0,r=max(D-1,x[n]-D); while(l<=r) { int mid=l+r>>1; if(solve(max(1,D-mid),D+mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans); }