枚举,二分,$RMQ$。
肯定是将连续一段中最大值免去花费,枚举起点之后,二分终点即可。可以证明单调性。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int T; int n; long long k,a[6000],b[6000],suma[6000],sumb[6000],dp[6000][30]; void RMQ_init() { for(int i=0;i<n;i++) dp[i][0]=a[i+1]; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } long long Max(int L,int R) { L--,R--; int k=0; while((1<<(k+1))<=R-L+1) k++; return max(dp[L][k],dp[R-(1<<k)+1][k]); } int main() { scanf("%d",&T); while(T--) { scanf("%d%lld",&n,&k); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); suma[i]=a[i]+suma[i-1]; } for(int i=1;i<=n;i++) { scanf("%lld",&b[i]); sumb[i]=sumb[i-1]+b[i]; } RMQ_init(); long long ans=0; for(int i=1;i<=n;i++) { int L=i,R=n,pos=-1; while(L<=R) { int mid= (L+R)/2; if(suma[mid]-suma[i-1]-Max(i,mid)<=k) pos=mid,L=mid+1; else R=mid-1; } ans=max(ans,sumb[pos]-sumb[i-1]); } printf("%lld ",ans); } return 0; }