2 条题解
-
-1
直接二分答案然后dp去check
线段树优化dp红红火火恍恍惚惚或或或或或或或或或或或或或或或或或
时间复杂度
#include<iostream> #include<cstring> #include<cstdio> #define N 50005 #define int long long using namespace std; bool Test_MLE_start; int T=1,n,m,ans=0; int a[N],dp[N]; struct tree{ int l,r,data; }t[N<<2]; inline int reads(){ char c=getchar(); int sum=0,f=1; while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); } while(isdigit(c)){ sum=(sum<<3)+(sum<<1)+(c^'0'); c=getchar(); } return sum*f; } inline void files(){ freopen("E.in","r",stdin); // freopen("std.out","w",stdout); } inline void clr(){ // Don't forget! } void pushup(int p){ int x=p<<1,y=p<<1|1; t[p].data=min(t[x].data,t[y].data); } void builds(int p,int l,int r){ t[p].l=l,t[p].r=r; if(l==r) return; int mid=(l+r)>>1; int x=p<<1,y=p<<1|1; builds(x,l,mid),builds(y,mid+1,r); pushup(p); } void changes(int p,int l,int r,int d){ if(l<=t[p].l&&t[p].r<=r){ t[p].data=d; return; } int mid=(t[p].l+t[p].r)>>1; int x=p<<1,y=p<<1|1; if(l<=mid) changes(x,l,r,d); if(r>mid) changes(y,l,r,d); pushup(p); } int asks(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) return t[p].data; int mid=(t[p].l+t[p].r)>>1; int x=p<<1,y=p<<1|1; int ans=2e9; if(l<=mid) ans=min(ans,asks(x,l,r)); if(r>mid) ans=min(ans,asks(y,l,r)); pushup(p); return ans; } bool check(int k){ memset(dp,0,sizeof(dp)); builds(1,0,n+1); for(int i=1;i<=n+1;i++){ int x=asks(1,max(0ll,i-k-1),i-1); dp[i]=x+a[i]; changes(1,i,i,dp[i]); } // cout<<k<<":"; // for(int i=1;i<=n+1;i++) cout<<dp[i]<<" "; // puts(""); return dp[n+1]<=m; } bool Test_MLE_end; signed main(){ // printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0); // files(); // T=reads(); while(T--){ clr(); n=reads(),m=reads(); for(int i=1;i<=n;i++) a[i]=reads(); int L=1,R=n; while(L<=R){ int mid=(L+R)>>1; if(check(mid)){ ans=mid; R=mid-1; } else L=mid+1; } printf("%lld\n",ans); } return 0; }
- 1
信息
- ID
- 288
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 11
- 已通过
- 7
- 上传者