还是挺简单的,但是区间处理的时候要注意一下
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define maxn 200005 #define ll long long int dpmax[maxn][20],a[maxn],n; ll k; void ST(){ memset(dpmax,0,sizeof dpmax); for(int i=1;i<=n;i++) dpmax[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); } int query(int L,int R){ int k=log2(R-L+1); return max(dpmax[L][k],dpmax[R-(1<<k)+1][k]); } int judge(int m){//分成m组是否可行 ll tot=0; int len=n/m,cur=1;//每组len人 for(int i=1;i<=m;i++) tot+=query((i-1)*len+1,i*len); if(tot>k) return 1; return 0; } int main(){ while(scanf("%d%lld",&n,&k) && n>0){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); ST(); int l=1,r=n,ans=-1; while(l<=r){ int mid=l+r>>1; if(judge(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans); } }